From da213852f62583e2e0a9a9856c9757e395a1d1b9 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 17 Jun 2026 14:42:27 +0800 Subject: [PATCH 01/51] =?UTF-8?q?fix:=20=E9=B1=BC=E7=B1=BB=E5=A2=9E?= =?UTF-8?q?=E6=AE=96=E7=AB=99=E7=A7=91=E7=A0=94=E6=83=85=E5=86=B5=E5=88=97?= =?UTF-8?q?=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) { From 2c37ad6cb36adbb3ed9cbbaeaf291dbe2f4ea144 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 17 Jun 2026 15:20:22 +0800 Subject: [PATCH 02/51] =?UTF-8?q?feat:=20(=E5=85=A8=E8=BF=87=E7=A8=8B)?= =?UTF-8?q?=E5=A2=9E=E6=AE=96=E7=AB=99=E4=BA=8C=E7=BA=A7=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?:=20=E5=A2=9E=E6=AE=96=E6=94=BE=E6=B5=81=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fb/controller/FbMsfbrdmController.java | 6 + .../qgc_env/fb/entity/vo/FbMsfbrdmQgcVo.java | 47 ++ .../fb/entity/vo/FbReleaseDirectionVo.java | 21 + .../qgc_env/fb/service/FbStationService.java | 3 + .../fb/service/impl/FbStationServiceImpl.java | 511 ++++++++++++++++++ .../fp/service/impl/FpBuildServiceImpl.java | 10 +- 6 files changed, 593 insertions(+), 5 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbMsfbrdmQgcVo.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbReleaseDirectionVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbMsfbrdmController.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbMsfbrdmController.java index 0606b62e..3a70e79a 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbMsfbrdmController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbMsfbrdmController.java @@ -26,4 +26,10 @@ public class FbMsfbrdmController { public ResponseResult getFbFlData(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(fbStationService.getFbFlDataKendoListCust(dataSourceRequest)); } + + @PostMapping("/qgc/GetKendoListCust") + @Operation(summary = "(全过程)增殖站二级页面: 增殖放流情况") + public ResponseResult getQgcKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(fbStationService.getQgcMsfbrdmKendoListCust(dataSourceRequest)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbMsfbrdmQgcVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbMsfbrdmQgcVo.java new file mode 100644 index 00000000..e93d3e87 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbMsfbrdmQgcVo.java @@ -0,0 +1,47 @@ +package com.yfd.platform.qgc_env.fb.entity.vo; + +import lombok.Data; + +import java.util.List; + +@Data +public class FbMsfbrdmQgcVo { + + private String stcd; + + private String stnm; + + private String baseId; + + private String baseName; + + private String rstcd; + + private String ennm; + + private Integer bldstt; + + private Integer hydrodtin; + + private Integer runState; + + private String runStateName; + + private String ftp; + + private String ftpName; + + private Long fcntjh; + + private Long fcntjc; + + private String flyr; + + private String fsz; + + private String fwet; + + private String fid; + + private List directionVoList; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbReleaseDirectionVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbReleaseDirectionVo.java new file mode 100644 index 00000000..c8137b2c --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbReleaseDirectionVo.java @@ -0,0 +1,21 @@ +package com.yfd.platform.qgc_env.fb.entity.vo; + +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +public class FbReleaseDirectionVo { + + private String flstcd; + + private String flstnm; + + private Long flfnct; + + private String flyr; + + private String ftp; + + private String stcd; +} 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 d62ac4d5..66d93a2b 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.FbMsfbrdmQgcVo; 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; @@ -22,6 +23,8 @@ public interface FbStationService { DataSourceResult getFbFlDataKendoListCust(DataSourceRequest dataSourceRequest); + DataSourceResult getQgcMsfbrdmKendoListCust(DataSourceRequest dataSourceRequest); + DataSourceResult getQgcBsmfRKendoListCust(DataSourceRequest dataSourceRequest); DataSourceResult getBsmfRFishKendoListCust(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 fdb4c098..6387b803 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 @@ -17,7 +17,9 @@ import com.yfd.platform.qgc_env.fb.entity.vo.FbBsmfRFishSummaryVo; 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.FbMsfbrdmQgcVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbRelatedYrVo; +import com.yfd.platform.qgc_env.fb.entity.vo.FbReleaseDirectionVo; 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; @@ -81,6 +83,16 @@ public class FbStationServiceImpl implements FbStationService { return queryFbFlDataDetailList(dataSourceRequest, loadOptions); } + @Override + public DataSourceResult getQgcMsfbrdmKendoListCust(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + GroupingInfo[] groups = loadOptions == null ? null : loadOptions.getGroup(); + if (groups != null && groups.length > 0) { + return queryQgcMsfbrdmGroupList(dataSourceRequest, loadOptions, groups); + } + return queryQgcMsfbrdmDetailList(dataSourceRequest, loadOptions); + } + @Override public DataSourceResult getQgcBsmfRKendoListCust(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); @@ -732,6 +744,505 @@ public class FbStationServiceImpl implements FbStationService { return sql.toString(); } + private DataSourceResult queryQgcMsfbrdmDetailList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions) { + Map paramMap = new HashMap<>(); + String startTime = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "startTime"); + String endTime = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "endTime"); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(buildQgcMsfbrdmDetailSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect())) + .append(" FROM (") + .append(buildQgcMsfbrdmCoreSql(parseDateTimeSafely(startTime), parseDateTimeSafely(endTime), paramMap)) + .append(") t WHERE 1 = 1 "); + + String filterSql = buildQgcMsfbrdmFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, + new int[]{0} + ); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + sql.append(buildQgcMsfbrdmOrderBySql(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, FbMsfbrdmQgcVo.class + ); + enrichQgcMsfbrdmDirections(list, parseDateTimeSafely(startTime), parseDateTimeSafely(endTime)); + deduplicateQgcMsfbrdmFids(list); + 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 queryQgcMsfbrdmGroupList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions, + GroupingInfo[] groupInfos) { + Map paramMap = new HashMap<>(); + String startTime = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "startTime"); + String endTime = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "endTime"); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT * FROM (") + .append(buildQgcMsfbrdmCoreSql(parseDateTimeSafely(startTime), parseDateTimeSafely(endTime), paramMap)) + .append(") t WHERE 1 = 1 "); + + String filterSql = buildQgcMsfbrdmFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, + new int[]{0} + ); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + + String groupSql = buildQgcMsfbrdmGroupSql(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 { + List grouped = new GroupHelper().group(rows, Arrays.asList(groupInfos)); + populateQgcMsfbrdmGroupKeyNames(grouped); + result.setData((List) (List) grouped); + } + result.setTotal(0L); + result.setAggregates(new HashMap<>()); + return result; + } + + private String buildQgcMsfbrdmCoreSql(Date startTime, Date endTime, Map paramMap) { + Integer year = startTime == null ? null : Integer.parseInt(DateUtil.format(startTime, "yyyy")); + String ftpCodeExpr = "COALESCE(TO_CHAR(NVL(relRv.ZY_FISH_ID, relRv.FISH_ID)), " + + "TO_CHAR(NVL(relZy.ZY_FISH_ID, relZy.FISH_ID)), TO_CHAR(stat.FTP))"; + String ftpNameExpr = buildFishNameExpr("stat.FTP"); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT fb.STCD AS stcd, ") + .append("fb.STNM AS stnm, ") + .append("fb.RSTCD AS rstcd, ") + .append("eng.ENNM AS ennm, ") + .append("fb.BASE_ID AS baseId, ") + .append("hb.BASENAME AS baseName, ") + .append("TO_CHAR(mt.YR) AS flyr, ") + .append(ftpCodeExpr).append(" AS ftp, ") + .append(ftpNameExpr).append(" AS ftpName, ") + .append("stat.FCNTJH AS fcntjh, ") + .append("stat.FCNTJC AS fcntjc, ") + .append("stat.FSZ AS fsz, ") + .append("stat.FWET AS fwet, ") + .append("fb.DTIN AS hydrodtin, ") + .append("fb.BLDSTT_CODE AS bldstt, ") + .append("mt.STD_SSTATE AS runState, ") + .append("CASE mt.STD_SSTATE ") + .append(" WHEN 0 THEN '数据未接入' ") + .append(" WHEN 1 THEN '正常运行' ") + .append(" WHEN 2 THEN '未正常报送数据' ") + .append(" WHEN 3 THEN '未正常运行' ") + .append(" ELSE NULL END AS runStateName, ") + .append("stat.FID AS fid ") + .append("FROM MS_STSTATE_T mt ") + .append("INNER JOIN SD_FBRD_B_H fb ON fb.STCD = mt.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("LEFT JOIN (") + .append(" SELECT COALESCE(planAgg.STCD, actualAgg.STCD) AS STCD, ") + .append(" COALESCE(planAgg.FTP, actualAgg.FTP) AS FTP, ") + .append(" COALESCE(planAgg.FLYR, actualAgg.FLYR) AS FLYR, ") + .append(" planAgg.FCNTJH AS FCNTJH, ") + .append(" actualAgg.FCNTJC AS FCNTJC, ") + .append(" actualAgg.FID AS FID, ") + .append(" actualAgg.FSZ AS FSZ, ") + .append(" actualAgg.FWET AS FWET ") + .append(" FROM (") + .append(" SELECT plan.RSTCD AS STCD, ") + .append(" planDet.FTP AS FTP, ") + .append(" TO_NUMBER(TO_CHAR(plan.PLANSD, 'YYYY')) AS FLYR, ") + .append(" SUM(planDet.FCNT) AS FCNTJH ") + .append(" FROM SD_ENGFRPLAN_B plan ") + .append(" INNER JOIN SD_ENGFRPLANDET_B planDet ON plan.ID = planDet.RPJH_ID ") + .append(" AND NVL(planDet.IS_DELETED, 0) = 0 ") + .append(" AND planDet.FTP IS NOT NULL ") + .append(" WHERE NVL(plan.IS_DELETED, 0) = 0 "); + if (startTime != null) { + paramMap.put("qgcMsfbrdmPlanStart", startTime); + sql.append(" AND plan.PLANSD >= #{map.qgcMsfbrdmPlanStart} "); + } + if (endTime != null) { + paramMap.put("qgcMsfbrdmPlanEnd", endTime); + sql.append(" AND plan.PLANED <= #{map.qgcMsfbrdmPlanEnd} "); + } + sql.append(" GROUP BY plan.RSTCD, planDet.FTP, TO_NUMBER(TO_CHAR(plan.PLANSD, 'YYYY')) ") + .append(" ) planAgg ") + .append(" FULL OUTER JOIN (") + .append(" SELECT run.RSTCD AS STCD, ") + .append(" actualDet.FTP AS FTP, ") + .append(" TO_NUMBER(TO_CHAR(run.TM, 'YYYY')) AS FLYR, ") + .append(" SUM(actualDet.FCNT) AS FCNTJC, ") + .append(" LISTAGG(run.FPRFID || ',' || run.FLRFID || ',' || run.BRRFID || ',' || run.BRFFID, ',') ") + .append(" WITHIN GROUP (ORDER BY run.ID) AS FID, ") + .append(" MAX(actualDet.FSZ) AS FSZ, ") + .append(" MAX(actualDet.FWET) AS FWET ") + .append(" FROM SD_ENGFR_R run ") + .append(" INNER JOIN SD_RPIMNFISH_R actualDet ON run.ID = actualDet.RPIMN_ID ") + .append(" AND NVL(actualDet.IS_DELETED, 0) = 0 ") + .append(" AND actualDet.FTP IS NOT NULL ") + .append(" WHERE NVL(run.IS_DELETED, 0) = 0 "); + if (startTime != null) { + paramMap.put("qgcMsfbrdmRunStart", startTime); + sql.append(" AND run.TM >= #{map.qgcMsfbrdmRunStart} "); + } + if (endTime != null) { + paramMap.put("qgcMsfbrdmRunEnd", endTime); + sql.append(" AND run.TM <= #{map.qgcMsfbrdmRunEnd} "); + } + sql.append(" GROUP BY run.RSTCD, actualDet.FTP, TO_NUMBER(TO_CHAR(run.TM, 'YYYY')) ") + .append(" ) actualAgg ") + .append(" ON planAgg.STCD = actualAgg.STCD ") + .append(" AND NVL(planAgg.FTP, '~') = NVL(actualAgg.FTP, '~') ") + .append(" AND NVL(planAgg.FLYR, -1) = NVL(actualAgg.FLYR, -1) ") + .append(") stat ON stat.STCD = mt.STCD AND stat.FLYR = mt.YR ") + .append(buildFishJoinSql("stat.FTP", "fb.HBRVCD")) + .append("WHERE NVL(mt.IS_DELETED, 0) = 0 ") + .append(" AND mt.STTP_CODE = 'FB' "); + if (year != null) { + paramMap.put("qgcMsfbrdmYear", year); + sql.append(" AND mt.YR = #{map.qgcMsfbrdmYear} "); + } + return sql.toString(); + } + + private void enrichQgcMsfbrdmDirections(List list, Date startTime, Date endTime) { + if (CollUtil.isEmpty(list)) { + return; + } + Map paramMap = new HashMap<>(); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT run.STCD AS flstcd, ") + .append(" eng.ENNM AS flstnm, ") + .append(" SUM(det.FCNT) AS flfnct, ") + .append(" TO_CHAR(run.TM, 'YYYY') AS flyr, ") + .append(" COALESCE(TO_CHAR(NVL(relRv.ZY_FISH_ID, relRv.FISH_ID)), ") + .append(" TO_CHAR(NVL(relZy.ZY_FISH_ID, relZy.FISH_ID)), TO_CHAR(det.FTP)) AS ftp, ") + .append(" run.RSTCD AS stcd ") + .append("FROM SD_ENGFR_R run ") + .append("INNER JOIN SD_RPIMNFISH_R det ON det.RPIMN_ID = run.ID ") + .append(" AND NVL(det.IS_DELETED, 0) = 0 ") + .append("LEFT JOIN SD_FBRD_B_H fb ON fb.STCD = run.RSTCD ") + .append(" AND NVL(fb.IS_DELETED, 0) = 0 ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = run.STCD ") + .append(" AND NVL(eng.IS_DELETED, 0) = 0 ") + .append(buildFishJoinSql("det.FTP", "fb.HBRVCD")) + .append("WHERE NVL(run.IS_DELETED, 0) = 0 "); + if (startTime != null) { + paramMap.put("qgcMsfbrdmDirStart", startTime); + sql.append(" AND run.TM >= #{map.qgcMsfbrdmDirStart} "); + } + if (endTime != null) { + paramMap.put("qgcMsfbrdmDirEnd", endTime); + sql.append(" AND run.TM <= #{map.qgcMsfbrdmDirEnd} "); + } + sql.append("GROUP BY run.STCD, eng.ENNM, TO_CHAR(run.TM, 'YYYY'), ") + .append(" COALESCE(TO_CHAR(NVL(relRv.ZY_FISH_ID, relRv.FISH_ID)), ") + .append(" TO_CHAR(NVL(relZy.ZY_FISH_ID, relZy.FISH_ID)), TO_CHAR(det.FTP)), ") + .append(" run.RSTCD "); + + List directions = microservicDynamicSQLMapper.pageAllListWithResultType( + null, sql.toString(), paramMap, FbReleaseDirectionVo.class + ); + if (CollUtil.isEmpty(directions)) { + return; + } + Map> directionMap = directions.stream() + .collect(Collectors.groupingBy( + item -> StrUtil.blankToDefault(item.getStcd(), "") + "|" + + StrUtil.blankToDefault(item.getFtp(), "") + "|" + + StrUtil.blankToDefault(item.getFlyr(), ""), + LinkedHashMap::new, + Collectors.toList() + )); + for (FbMsfbrdmQgcVo item : list) { + String key = StrUtil.blankToDefault(item.getStcd(), "") + "|" + + StrUtil.blankToDefault(item.getFtp(), "") + "|" + + StrUtil.blankToDefault(item.getFlyr(), ""); + item.setDirectionVoList(directionMap.getOrDefault(key, Collections.emptyList())); + } + } + + private void deduplicateQgcMsfbrdmFids(List list) { + if (CollUtil.isEmpty(list)) { + return; + } + for (FbMsfbrdmQgcVo item : list) { + if (item == null || StrUtil.isBlank(item.getFid())) { + continue; + } + Set fidSet = Arrays.stream(item.getFid().split(",")) + .map(StrUtil::trim) + .filter(StrUtil::isNotBlank) + .collect(Collectors.toCollection(LinkedHashSet::new)); + item.setFid(fidSet.isEmpty() ? null : String.join(",", fidSet)); + } + } + + private String buildQgcMsfbrdmDetailSelectSql(List select) { + List fields = CollUtil.isEmpty(select) + ? List.of("stcd", "stnm", "baseId", "baseName", "rstcd", "ennm", "bldstt", + "hydrodtin", "runState", "runStateName", "ftp", "ftpName", "fcntjh", "fcntjc", + "flyr", "fsz", "fwet", "fid") + : select; + List selectParts = new ArrayList<>(); + for (String field : fields) { + String column = mapQgcMsfbrdmColumn(field); + if (StrUtil.isNotBlank(column)) { + selectParts.add(column + " AS " + field); + } + } + if (selectParts.isEmpty()) { + selectParts.add("t.stcd AS stcd"); + } + return String.join(", ", selectParts); + } + + private String buildQgcMsfbrdmFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildQgcMsfbrdmLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildQgcMsfbrdmFilterCondition(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 buildQgcMsfbrdmLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String column = mapQgcMsfbrdmColumn(filter.getField()); + 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 = "qgcMsfbrdmP" + indexHolder[0]++; + paramMap.put(key, normalizeQgcMsfbrdmValue(filter.getField(), item)); + placeholders.add("#{map." + key + "}"); + } + return column + " IN (" + String.join(", ", placeholders) + ")"; + } + if (value == null) { + return ""; + } + String key = "qgcMsfbrdmP" + indexHolder[0]++; + Object normalizedValue = normalizeQgcMsfbrdmValue(filter.getField(), 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 buildQgcMsfbrdmOrderBySql(List sortDescriptors) { + if (CollUtil.isEmpty(sortDescriptors)) { + return " ORDER BY t.flyr DESC, t.stnm ASC, t.ftpName ASC"; + } + List parts = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor descriptor : sortDescriptors) { + String column = mapQgcMsfbrdmColumn(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.flyr DESC, t.stnm ASC, t.ftpName ASC"; + } + return " ORDER BY " + String.join(", ", parts); + } + + private String buildQgcMsfbrdmGroupSql(String baseSql, List groups) { + if (CollUtil.isEmpty(groups)) { + return baseSql; + } + List validGroups = groups.stream() + .filter(group -> StrUtil.isNotBlank(mapQgcMsfbrdmColumn(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 mapQgcMsfbrdmColumn(String field) { + return switch (field) { + case "stcd" -> "t.stcd"; + case "stnm" -> "t.stnm"; + case "baseId" -> "t.baseId"; + case "baseName" -> "t.baseName"; + case "rstcd" -> "t.rstcd"; + case "ennm" -> "t.ennm"; + case "bldstt" -> "t.bldstt"; + case "hydrodtin" -> "t.hydrodtin"; + case "runState" -> "t.runState"; + case "runStateName" -> "t.runStateName"; + case "ftp" -> "t.ftp"; + case "ftpName" -> "t.ftpName"; + case "fcntjh" -> "t.fcntjh"; + case "fcntjc" -> "t.fcntjc"; + case "flyr" -> "t.flyr"; + case "fsz" -> "t.fsz"; + case "fwet" -> "t.fwet"; + case "fid" -> "t.fid"; + default -> ""; + }; + } + + private Object normalizeQgcMsfbrdmValue(String field, Object value) { + if (value == null) { + return null; + } + return switch (field) { + case "fcntjh", "fcntjc", "bldstt", "hydrodtin", "runState" -> Integer.valueOf(String.valueOf(value)); + case "flyr" -> String.valueOf(value); + default -> value; + }; + } + + @SuppressWarnings("unchecked") + private void populateQgcMsfbrdmGroupKeyNames(List groups) { + if (CollUtil.isEmpty(groups)) { + return; + } + for (Group group : groups) { + if (group == null) { + continue; + } + if ("runState".equals(group.getField()) || "runStateName".equals(group.getField())) { + group.setKeyName(resolveQgcMsfbrdmRunStateName(group.getKey())); + } + if (CollUtil.isNotEmpty(group.getItems()) && group.getItems().get(0) instanceof Group) { + populateQgcMsfbrdmGroupKeyNames((List) group.getItems()); + } + } + } + + private String resolveQgcMsfbrdmRunStateName(Object value) { + if (value == null) { + return null; + } + String text = String.valueOf(value); + return switch (text) { + case "0" -> "数据未接入"; + case "1" -> "正常运行"; + case "2" -> "未正常报送数据"; + case "3" -> "未正常运行"; + default -> text; + }; + } + private DataSourceResult queryQgcBsmfRDetailList(DataSourceRequest dataSourceRequest, DataSourceLoadOptionsBase loadOptions) { Map paramMap = new HashMap<>(); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpBuildServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpBuildServiceImpl.java index 88b8a6f9..a5b7963a 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpBuildServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpBuildServiceImpl.java @@ -136,15 +136,15 @@ public class FpBuildServiceImpl implements FpBuildService { String sql = "SELECT DISTINCT " + " fish.ID AS id, " + " fish.NAME AS name " + - "FROM SD_FPSS_B_H fp " + - "INNER JOIN SD_ENGINFO_B_H eng ON eng.STCD = fp.RSTCD " + - " AND NVL(eng.IS_DELETED, 0) = 0 " + - "INNER JOIN SD_FISHDICTORY_RLTN_B rel ON rel.RVCD = eng.HBRVCD " + + "FROM SD_FBRD_B_H fb " + +// "INNER JOIN SD_ENGINFO_B_H eng ON eng.STCD = fb.RSTCD " + +// " AND NVL(eng.IS_DELETED, 0) = 0 " + + "INNER JOIN SD_FISHDICTORY_RLTN_B rel ON rel.BASE_ID = fb.BASE_ID " + " AND NVL(rel.IS_DELETED, 0) = 0 " + "INNER JOIN SD_FISHDICTORY_B fish ON fish.ID = NVL(rel.ZY_FISH_ID, rel.FISH_ID) " + " AND NVL(fish.IS_DELETED, 0) = 0 " + " AND NVL(fish.ENABLE, 1) = 1 " + - "WHERE fp.STCD = #{map.stcd} " + + "WHERE fb.STCD = #{map.stcd} " + "ORDER BY fish.NAME"; List list = microservicDynamicSQLMapper.getAllListWithResultType( From da514b286cc995dea2e5ed222839f2fd8cd7ca58 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 17 Jun 2026 16:08:01 +0800 Subject: [PATCH 03/51] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qgc_env/fb/service/impl/FbStationServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 6387b803..ec88961c 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 @@ -846,7 +846,7 @@ public class FbStationServiceImpl implements FbStationService { .append("stat.FID AS fid ") .append("FROM MS_STSTATE_T mt ") .append("INNER JOIN SD_FBRD_B_H fb ON fb.STCD = mt.STCD ") - .append(" AND NVL(fb.IS_DELETED, 0) = 0 ") +// .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 ") @@ -936,7 +936,7 @@ public class FbStationServiceImpl implements FbStationService { .append("INNER JOIN SD_RPIMNFISH_R det ON det.RPIMN_ID = run.ID ") .append(" AND NVL(det.IS_DELETED, 0) = 0 ") .append("LEFT JOIN SD_FBRD_B_H fb ON fb.STCD = run.RSTCD ") - .append(" AND NVL(fb.IS_DELETED, 0) = 0 ") +// .append(" AND NVL(fb.IS_DELETED, 0) = 0 ") .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = run.STCD ") .append(" AND NVL(eng.IS_DELETED, 0) = 0 ") .append(buildFishJoinSql("det.FTP", "fb.HBRVCD")) From f37cb335e7835323e88a88fabb3499ebe655fec8 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 17 Jun 2026 18:11:12 +0800 Subject: [PATCH 04/51] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yfd/platform/qgc_eng/eq/entity/vo/EngEqVmsstbprptVo.java | 3 +++ .../platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqVmsstbprptVo.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqVmsstbprptVo.java index 04a7d016..e3a444c1 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqVmsstbprptVo.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqVmsstbprptVo.java @@ -56,6 +56,9 @@ public class EngEqVmsstbprptVo implements Serializable { @Schema(description = "环保数据接入状态") private Integer dtinEnv; + @Schema(description = "接入状态") + private Integer dtin; + @Schema(description = "基地排序") private Integer baseStepSort; diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java index 4b3fb30a..b227a998 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java @@ -2480,6 +2480,7 @@ public class EngEqDataServiceImpl implements EngEqDataService { "eng.BLDSTT AS bldstt, " + "eng.BLDSTT_CODE AS bldsttCcode, " + "eng.DTIN_ENV AS dtinEnv, " + + "eng.DTIN AS dtin, " + "NVL(hb.ORDER_INDEX, 999999) AS baseStepSort, " + "NVL(along.ORDER_INDEX, 999999) AS rvcdStepSort, " + "NVL(eng.ORDER_INDEX, 999999) AS rstcdStepSort, " + @@ -2528,6 +2529,7 @@ public class EngEqDataServiceImpl implements EngEqDataService { columns.put("prsc", "t.prsc AS prsc"); columns.put("bldstt", "t.bldstt AS bldstt"); columns.put("bldsttCcode", "t.bldsttCcode AS bldsttCcode"); + columns.put("dtin", "t.dtin AS dtin"); columns.put("dtinEnv", "t.dtinEnv AS dtinEnv"); columns.put("baseStepSort", "t.baseStepSort AS baseStepSort"); columns.put("rvcdStepSort", "t.rvcdStepSort AS rvcdStepSort"); @@ -4502,6 +4504,7 @@ public class EngEqDataServiceImpl implements EngEqDataService { case "bldstt" -> "t.bldstt"; case "bldsttCcode" -> "t.bldsttCcode"; case "dtinEnv" -> "t.dtinEnv"; + case "DTIN" -> "t.dtin"; case "baseStepSort" -> "NVL(t.baseStepSort, 999999)"; case "rvcdStepSort" -> "NVL(t.rvcdStepSort, 999999)"; case "rstcdStepSort" -> "NVL(t.rstcdStepSort, 999999)"; From d64894905ab7d13bec7c5773e4fc4ef6d4ecaca1 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 17 Jun 2026 18:27:12 +0800 Subject: [PATCH 05/51] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java index b227a998..eea8d641 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java @@ -2477,6 +2477,7 @@ public class EngEqDataServiceImpl implements EngEqDataService { "eng.RVCD AS rvcd, " + "rv.RVNM AS rvcdName, " + "eng.PRSC AS prsc, " + + "eng.RUN_STATE AS runState, " + "eng.BLDSTT AS bldstt, " + "eng.BLDSTT_CODE AS bldsttCcode, " + "eng.DTIN_ENV AS dtinEnv, " + @@ -2530,6 +2531,7 @@ public class EngEqDataServiceImpl implements EngEqDataService { columns.put("bldstt", "t.bldstt AS bldstt"); columns.put("bldsttCcode", "t.bldsttCcode AS bldsttCcode"); columns.put("dtin", "t.dtin AS dtin"); + columns.put("runState", "t.runState AS runState"); columns.put("dtinEnv", "t.dtinEnv AS dtinEnv"); columns.put("baseStepSort", "t.baseStepSort AS baseStepSort"); columns.put("rvcdStepSort", "t.rvcdStepSort AS rvcdStepSort"); @@ -4505,6 +4507,7 @@ public class EngEqDataServiceImpl implements EngEqDataService { case "bldsttCcode" -> "t.bldsttCcode"; case "dtinEnv" -> "t.dtinEnv"; case "DTIN" -> "t.dtin"; + case "runState" -> "t.runState"; case "baseStepSort" -> "NVL(t.baseStepSort, 999999)"; case "rvcdStepSort" -> "NVL(t.rvcdStepSort, 999999)"; case "rstcdStepSort" -> "NVL(t.rstcdStepSort, 999999)"; From 725384f09341b2d4febe2eac603493e9d6445fce Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 17 Jun 2026 19:08:32 +0800 Subject: [PATCH 06/51] =?UTF-8?q?feat:=20=E7=94=B5=E7=AB=99=E7=94=9F?= =?UTF-8?q?=E6=80=81=E6=B5=81=E9=87=8F=E7=BB=9F=E8=AE=A1=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=EF=BC=88=E7=94=B5=E7=AB=99=E5=B7=A6=E8=BF=9E=E6=8E=A5=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qgc_eng/eq/controller/EngEqDataController.java | 6 ++++++ .../qgc_eng/eq/service/impl/EngEqDataServiceImpl.java | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java index 9421dcd7..64e9c879 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java @@ -56,6 +56,12 @@ public class EngEqDataController { return ResponseResult.successData(engEqDataService.getIntervalKendoListCust(dataSourceRequest)); } + @PostMapping("/to/eq/GetKendoListCust") + @Operation(summary = "电站生态流量统计查询(电站左连接)") + public ResponseResult getToEqKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(engEqDataService.getIntervalKendoListCust(dataSourceRequest)); + } + @PostMapping("/msstbprpt/GetKendoList") @Operation(summary = "电站基础信息查询") public ResponseResult getMsstbprptList(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java index eea8d641..5f898876 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java @@ -1964,7 +1964,9 @@ public class EngEqDataServiceImpl implements EngEqDataService { 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))); + List grouped = new GroupHelper().group(rows, Arrays.asList(groupInfos)); + populateHourDayGroupKeyNames(grouped); + result.setData((List) (List) grouped); } result.setTotal(0L); result.setAggregates(new HashMap<>()); @@ -2024,6 +2026,7 @@ public class EngEqDataServiceImpl implements EngEqDataService { return "SELECT " + "eng.STCD AS stcd, " + + "eng.RGCP AS rgcp, " + "eng.ENNM AS stnm, " + "eng.ENNM AS ennm, " + "'ENG' AS sttp, " + @@ -2237,6 +2240,7 @@ public class EngEqDataServiceImpl implements EngEqDataService { columns.put("dtmel", "t.dtmel AS dtmel"); columns.put("dtin", "t.dtin AS dtin"); columns.put("dtinEnv", "t.dtinEnv AS dtinEnv"); + columns.put("rgcp", "t.rgcp AS rgcp"); columns.put("prsc", "t.prsc AS prsc"); columns.put("bldsttCcode", "t.bldsttCcode AS bldsttCcode"); columns.put("qi", "t.qi AS qi"); @@ -4447,6 +4451,7 @@ public class EngEqDataServiceImpl implements EngEqDataService { } return switch (field) { case "stcd" -> "t.stcd"; + case "rgcpCode" -> "t.rgcp"; case "stnm", "ennm" -> "t.ennm"; case "sttp", "sttpCode" -> "t.sttpCode"; case "baseId" -> "t.baseId"; From 51f5e9959b36bc6fdad480e86e62bd9c1ba8874e Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 17 Jun 2026 19:27:02 +0800 Subject: [PATCH 07/51] =?UTF-8?q?feat:=20=E9=B1=BC=E7=B1=BB=E8=B0=83?= =?UTF-8?q?=E6=9F=A5=E8=A3=85=E7=BD=AE=E8=AF=A6=E6=83=85=E6=95=B0=E6=8D=AE?= =?UTF-8?q?&=E8=8E=B7=E5=8F=96=E9=B1=BC=E7=A7=8D=E7=B1=BB=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fpr/controller/FprMonitorController.java | 16 ++ .../qgc_env/fpr/entity/vo/FprdDetailVo.java | 36 +++ .../fpr/service/FprMonitorService.java | 5 + .../service/impl/FprMonitorServiceImpl.java | 215 ++++++++++++++++++ 4 files changed, 272 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/fpr/entity/vo/FprdDetailVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fpr/controller/FprMonitorController.java b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/controller/FprMonitorController.java index a5f31b87..badaaf3f 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fpr/controller/FprMonitorController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/controller/FprMonitorController.java @@ -1,8 +1,10 @@ package com.yfd.platform.qgc_env.fpr.controller; import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.config.ResponseResult; import com.yfd.platform.qgc_env.fpr.entity.ao.FprdRunDataAo; +import com.yfd.platform.qgc_env.fpr.entity.vo.FprdDetailVo; import com.yfd.platform.qgc_eng.eq.service.EngEqDataService; import com.yfd.platform.qgc_env.fpr.entity.vo.FprFtpChangeInfoVo; import com.yfd.platform.qgc_env.fpr.entity.vo.FprdRunDataInfoVo; @@ -64,6 +66,20 @@ public class FprMonitorController { return ResponseResult.successData(result); } + @PostMapping("/sdFprdR/GetKendoListCust") + @Operation(summary = "鱼类调查装置详情数据") + public ResponseResult getFprdDetailList(@RequestBody DataSourceRequest dataSourceRequest) { + DataSourceResult result = fprMonitorService.getFprdDetailList(dataSourceRequest); + return ResponseResult.successData(result); + } + + @PostMapping("/sdFprdR/getFishInfo") + @Operation(summary = "获取鱼种类信息") + public ResponseResult getFishInfo() { + List result = fprMonitorService.getFishInfo(); + return ResponseResult.successData(result); + } + @PostMapping("/wbsb/GetKendoList") @Operation(summary = "查询基地/基地流域树数据") public ResponseResult getWbsbList(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fpr/entity/vo/FprdDetailVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/entity/vo/FprdDetailVo.java new file mode 100644 index 00000000..d3c200f1 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/entity/vo/FprdDetailVo.java @@ -0,0 +1,36 @@ +package com.yfd.platform.qgc_env.fpr.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +@Data +@Schema(description = "鱼类调查装置详情数据") +public class FprdDetailVo { + + @Schema(description = "调查鱼类装置编码") + private String stcd; + + @Schema(description = "调查鱼类装置名称") + private String stnm; + + @Schema(description = "监测时间") + private Date tm; + + @Schema(description = "监测视频文件ID") + private String fid; + + @Schema(description = "鱼类名称") + private String name; + + @Schema(description = "鱼类数量") + private Long num; + + @Schema(description = "鱼尺寸") + private BigDecimal fsz; + + @Schema(description = "鱼重量") + private BigDecimal weight; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/FprMonitorService.java b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/FprMonitorService.java index c0c49dd4..4c450b84 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/FprMonitorService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/FprMonitorService.java @@ -6,6 +6,7 @@ import com.yfd.platform.qgc_env.fpr.entity.vo.FprFtpChangeInfoVo; import com.yfd.platform.qgc_env.fpr.entity.ao.FprdRunDataAo; import com.yfd.platform.qgc_env.fpr.entity.vo.FprFishDicVo; import com.yfd.platform.qgc_env.fpr.entity.vo.FprMsstbprptVo; +import com.yfd.platform.qgc_env.fpr.entity.vo.FprdDetailVo; import com.yfd.platform.qgc_env.fpr.entity.vo.FprdRunDataInfoVo; import com.yfd.platform.qgc_env.fpr.entity.vo.FprZyFishDicVo; @@ -22,4 +23,8 @@ public interface FprMonitorService { FprdRunDataInfoVo getFprdRunDataInfo(FprdRunDataAo ao); List getFtpChangeInfo(FprdRunDataAo ao); + + DataSourceResult getFprdDetailList(DataSourceRequest dataSourceRequest); + + List getFishInfo(); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/impl/FprMonitorServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/impl/FprMonitorServiceImpl.java index 2ab792b0..407488a4 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/impl/FprMonitorServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/impl/FprMonitorServiceImpl.java @@ -3,6 +3,7 @@ package com.yfd.platform.qgc_env.fpr.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.copier.CopyOptions; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yfd.platform.common.DataSourceLoadOptionsBase; @@ -16,6 +17,7 @@ import com.yfd.platform.qgc_env.fpr.entity.ao.FprdRunDataAo; import com.yfd.platform.qgc_env.fpr.entity.vo.FprFishDicVo; import com.yfd.platform.qgc_env.fpr.entity.vo.FprFtpChangeInfoVo; import com.yfd.platform.qgc_env.fpr.entity.vo.FprMsstbprptVo; +import com.yfd.platform.qgc_env.fpr.entity.vo.FprdDetailVo; import com.yfd.platform.qgc_env.fpr.entity.vo.FprdRunDataInfoVo; import com.yfd.platform.qgc_env.fpr.entity.vo.FprZyFishDicVo; import com.yfd.platform.qgc_env.fpr.service.FprMonitorService; @@ -25,6 +27,7 @@ import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Arrays; +import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -76,6 +79,53 @@ public class FprMonitorServiceImpl implements FprMonitorService { ); } + @Override + public DataSourceResult getFprdDetailList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + Map paramMap = new HashMap<>(); + String filterSql = buildFprdDetailFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, + new int[]{0} + ); + + StringBuilder sql = new StringBuilder("SELECT ") + .append(buildFprdDetailSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect())) + .append(" FROM (") + .append(buildFprdDetailBaseSql()) + .append(") t WHERE 1 = 1 "); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + sql.append(buildFprdDetailOrderBySql(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, FprdDetailVo.class + ); + + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + @Override + public List getFishInfo() { + List> rows = microservicDynamicSQLMapper.getAllList( + "SELECT DISTINCT NAME AS name FROM SD_FPRDFISH_R " + + "WHERE NVL(IS_DELETED, 0) = 0 AND NAME IS NOT NULL " + + "ORDER BY NAME", + null + ); + return rows.stream() + .map(row -> row.get("NAME")) + .filter(java.util.Objects::nonNull) + .map(String::valueOf) + .toList(); + } + @Override public DataSourceResult getMsstbprptList(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); @@ -430,6 +480,171 @@ public class FprMonitorServiceImpl implements FprMonitorService { return sql.toString(); } + private String buildFprdDetailBaseSql() { + return "SELECT " + + "run.STCD AS stcd, " + + "base.STNM AS stnm, " + + "run.TM AS tm, " + + "run.FLPTH AS fid, " + + "fish.NAME AS name, " + + "fish.NUM AS num, " + + "fish.FSZ AS fsz, " + + "fish.WEIGHT AS weight " + + "FROM SD_FPRD_R run " + + "INNER JOIN SD_FPRD_B_H base ON run.STCD = base.STCD " + + " AND base.STTP = 'FPRD' " + + " AND NVL(base.IS_DELETED, 0) = 0 " + + "INNER JOIN SD_FPRDFISH_R fish ON run.ID = fish.FPRDR_ID " + + " AND NVL(fish.IS_DELETED, 0) = 0 " + + "WHERE NVL(run.IS_DELETED, 0) = 0 "; + } + + private String buildFprdDetailSelectSql(List selectFields) { + LinkedHashMap columnMap = new LinkedHashMap<>(); + columnMap.put("stcd", "t.stcd AS stcd"); + columnMap.put("stnm", "t.stnm AS stnm"); + columnMap.put("tm", "t.tm AS tm"); + columnMap.put("fid", "t.fid AS fid"); + columnMap.put("name", "t.name AS name"); + columnMap.put("num", "t.num AS num"); + columnMap.put("fsz", "t.fsz AS fsz"); + columnMap.put("weight", "t.weight AS weight"); + if (CollUtil.isEmpty(selectFields)) { + return String.join(", ", columnMap.values()); + } + List columns = new ArrayList<>(); + for (String field : selectFields) { + String column = columnMap.get(field); + if (StrUtil.isNotBlank(column)) { + columns.add(column); + } + } + return columns.isEmpty() ? String.join(", ", columnMap.values()) : String.join(", ", columns); + } + + private String buildFprdDetailFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildFprdDetailLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildFprdDetailFilterCondition(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 buildFprdDetailLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String field = filter.getField(); + Object value = filter.getValue(); + if (value == null) { + return ""; + } + String key = "fprdDetailP" + indexHolder[0]++; + return switch (field) { + case "stcd" -> { + paramMap.put(key, String.valueOf(value)); + yield "t.stcd = #{map." + key + "}"; + } + case "name" -> { + paramMap.put(key, "%" + value + "%"); + yield "t.name LIKE #{map." + key + "}"; + } + case "startTime" -> { + Date date = parseFprdDate(value); + if (date == null) { + yield ""; + } + paramMap.put(key, date); + yield "t.tm >= #{map." + key + "}"; + } + case "endTime" -> { + Date date = parseFprdDate(value); + if (date == null) { + yield ""; + } + paramMap.put(key, date); + yield "t.tm <= #{map." + key + "}"; + } + case "tm" -> { + Date date = parseFprdDate(value); + if (date == null) { + yield ""; + } + paramMap.put(key, date); + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + yield switch (operator) { + case "gte" -> "t.tm >= #{map." + key + "}"; + case "lte" -> "t.tm <= #{map." + key + "}"; + case "gt" -> "t.tm > #{map." + key + "}"; + case "lt" -> "t.tm < #{map." + key + "}"; + default -> "t.tm = #{map." + key + "}"; + }; + } + default -> ""; + }; + } + + private String buildFprdDetailOrderBySql(List sorts) { + if (CollUtil.isEmpty(sorts)) { + return " ORDER BY t.tm DESC"; + } + List orderParts = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sorts) { + String column = switch (sort.getField()) { + case "stcd" -> "t.stcd"; + case "stnm" -> "t.stnm"; + case "tm" -> "t.tm"; + case "name" -> "t.name"; + case "num" -> "t.num"; + case "fsz" -> "t.fsz"; + case "weight" -> "t.weight"; + default -> ""; + }; + if (StrUtil.isBlank(column)) { + continue; + } + orderParts.add(column + ("desc".equalsIgnoreCase(sort.getDir()) ? " DESC" : " ASC")); + } + return orderParts.isEmpty() ? " ORDER BY t.tm DESC" : " ORDER BY " + String.join(", ", orderParts); + } + + private Date parseFprdDate(Object value) { + if (value == null) { + return null; + } + if (value instanceof Date date) { + return date; + } + String text = String.valueOf(value); + if (StrUtil.isBlank(text)) { + return null; + } + if (text.length() == 10) { + return DateUtil.parse(text, "yyyy-MM-dd"); + } + if (text.length() == 16) { + return DateUtil.parse(text, "yyyy-MM-dd HH:mm"); + } + return DateUtil.parse(text, "yyyy-MM-dd HH:mm:ss"); + } + private void validateFprdRunDataAo(FprdRunDataAo ao) { if (ao == null) { throw new BizException("请求参数不能为空."); From 13831737eb4987395be19edeaa33db995cb59c47 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 17 Jun 2026 19:30:33 +0800 Subject: [PATCH 08/51] =?UTF-8?q?feat:=20=E9=B1=BC=E7=B1=BB=E8=B0=83?= =?UTF-8?q?=E6=9F=A5=E8=A3=85=E7=BD=AE=E7=BB=9F=E8=AE=A1=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qgc_env/fpr/controller/FprMonitorController.java | 6 ++++++ .../yfd/platform/qgc_env/fpr/service/FprMonitorService.java | 2 ++ .../qgc_env/fpr/service/impl/FprMonitorServiceImpl.java | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fpr/controller/FprMonitorController.java b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/controller/FprMonitorController.java index badaaf3f..61cbb809 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fpr/controller/FprMonitorController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/controller/FprMonitorController.java @@ -40,6 +40,12 @@ public class FprMonitorController { return ResponseResult.successData(fprMonitorService.getMsstbprptList(dataSourceRequest)); } + @PostMapping("/vmsstbprpt/GetKendoList") + @Operation(summary = "鱼类调查装置统计查询") + public ResponseResult getVmsstbprptList(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(fprMonitorService.getVmsstbprptList(dataSourceRequest)); + } + @PostMapping("/fishDic/GetKendoList") @Operation(summary = "鱼类字典列表") public ResponseResult getFishDicList(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/FprMonitorService.java b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/FprMonitorService.java index 4c450b84..8681b405 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/FprMonitorService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/FprMonitorService.java @@ -16,6 +16,8 @@ public interface FprMonitorService { DataSourceResult getMsstbprptList(DataSourceRequest dataSourceRequest); + DataSourceResult getVmsstbprptList(DataSourceRequest dataSourceRequest); + DataSourceResult getFishDicList(DataSourceRequest dataSourceRequest); DataSourceResult getZyFishDicList(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/impl/FprMonitorServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/impl/FprMonitorServiceImpl.java index 407488a4..ab2cfaca 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/impl/FprMonitorServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fpr/service/impl/FprMonitorServiceImpl.java @@ -180,6 +180,11 @@ public class FprMonitorServiceImpl implements FprMonitorService { return result; } + @Override + public DataSourceResult getVmsstbprptList(DataSourceRequest dataSourceRequest) { + return getMsstbprptList(dataSourceRequest); + } + @Override public DataSourceResult getFishDicList(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); From 71802724b1ffae2718006cc1d297d066ab70fe2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=85=B4=E5=87=AF?= <2448379534@qq.com> Date: Thu, 18 Jun 2026 09:29:15 +0800 Subject: [PATCH 09/51] =?UTF-8?q?=E9=B1=BC=E7=B1=BB=E8=B0=83=E6=9F=A5?= =?UTF-8?q?=E8=A3=85=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/api/yldc/index.ts | 64 +++ .../src/assets/images/fish_survey_liang.png | Bin 0 -> 5992 bytes .../src/assets/images/fish_survey_shu.png | Bin 0 -> 6358 bytes .../src/assets/images/fish_survey_zhong.png | Bin 0 -> 6048 bytes .../components/CommonAttachmentModal.vue | 9 +- .../MapModal/components/NoLiveVideo.vue | 100 +++- frontend/src/components/MapModal/index.vue | 2 +- .../src/components/MapModal/setting.config.ts | 18 +- .../src/components/SidePanelItem/index.vue | 35 +- .../EnvironmentalQualityTwoLayers.vue | 8 +- .../TwoLayers/HJMZDTwoLays.vue | 2 +- .../modules/EnvironmentalQuality/index.vue | 8 +- frontend/src/modules/GYZLLB/index.vue | 2 +- .../chuixiangshuiwenChangeMod/index.vue | 105 ++-- .../src/modules/churukushuiwenMod/index.vue | 13 +- .../modules/fishSurvey/FishChangeTu/index.vue | 338 ++++++++++++ .../fishSurvey/FishIntroduce/index.vue | 500 +++++++++++------- .../modules/fishSurvey/FishVideo/index.vue | 170 ++++-- .../SurveyQingKuang/DeviceTableModal.vue | 407 ++++++++++++++ .../fishSurvey/SurveyQingKuang/index.vue | 177 +++++++ .../fishSurvey/ZhuanZhiIntroduce/index.vue | 462 +++++++++------- .../ModalPage/index.vue | 4 +- .../modules/qixidiliuliangbianhua/index.vue | 4 +- .../modules/qixidishuiwenbianhua/index.vue | 4 +- .../xianZhiYanChenBianHua/index.vue | 2 +- .../xieFangFenBu/index.vue | 2 +- .../ShengTaiLiuLiangDaBQKTwoLayer.vue | 3 +- .../src/modules/shengtaidabiaoMod/index.vue | 4 +- .../modules/shengtaidabiaoTwoMod/index.vue | 6 +- .../src/modules/shuiWenNianNeiFenBu/index.vue | 19 +- .../modules/shuizhijiancegongzuoQK/index.vue | 6 +- .../modules/stllyanchengChangeMod/index.vue | 2 +- frontend/src/store/modules/model.ts | 4 +- .../views/fish-survey/fishSurveyZhuanZhi.vue | 112 +++- .../components/LiveVideoBox.vue | 116 +++- .../shuiHuanJingZhiLiangZhuangKuang.vue | 2 +- 36 files changed, 2127 insertions(+), 583 deletions(-) create mode 100644 frontend/src/api/yldc/index.ts create mode 100644 frontend/src/assets/images/fish_survey_liang.png create mode 100644 frontend/src/assets/images/fish_survey_shu.png create mode 100644 frontend/src/assets/images/fish_survey_zhong.png create mode 100644 frontend/src/modules/fishSurvey/FishChangeTu/index.vue create mode 100644 frontend/src/modules/fishSurvey/SurveyQingKuang/DeviceTableModal.vue create mode 100644 frontend/src/modules/fishSurvey/SurveyQingKuang/index.vue diff --git a/frontend/src/api/yldc/index.ts b/frontend/src/api/yldc/index.ts new file mode 100644 index 00000000..4643b2f1 --- /dev/null +++ b/frontend/src/api/yldc/index.ts @@ -0,0 +1,64 @@ +import request from '@/utils/request'; +//获取有数据的流域 +export function wbsbGetKendoList(data: any) { + return request({ + url: '/fpr/wbsb/GetKendoList', + method: 'post', + data + }); +} +//获取鱼类调查装置 +export function msstbprptGetKendoList(data: any) { + return request({ + url: '/fpr/msstbprpt/GetKendoList', + method: 'post', + data + }); +} +//获取鱼类介绍 +export function fishDicGetKendoList(data: any) { + return request({ + url: '/fpr/fishDic/GetKendoList', + method: 'post', + data + }); +} +//获取鱼类调查统计数据 +export function getFprdDataInfo(data: any) { + return request({ + url: '/fpr/sdFprdR/getFprdDataInfo', + method: 'post', + data + }); +} +// +export function sdFprdRGetKendoListCust(data: any) { + return request({ + url: '/fpr/sdFprdR/GetKendoListCust', + method: 'post', + data + }); +} +//装置名称 /api/dec-lygk-base-server/base/vmsstbprpt/GetKendoList +export function vmsstbprptGetKendoList(data: any) { + return request({ + url: '/fpr/vmsstbprpt/GetKendoList', + method: 'post', + data + }); +} +//鱼种类 /api/wmp-env-server/sdFprdR/getFishInfo +export function sdFprdRgetFishInfo() { + return request({ + url: '/fpr/sdFprdR/getFishInfo', + method: 'post', + }); +} +//获取鱼类变化信息 +export function sdFprdRGetFtpChangeInfo(data: { baseId: string; year: string }) { + return request({ + url: '/fpr/sdFprdR/getFtpChangeInfo', + method: 'post', + data + }); +} \ No newline at end of file diff --git a/frontend/src/assets/images/fish_survey_liang.png b/frontend/src/assets/images/fish_survey_liang.png new file mode 100644 index 0000000000000000000000000000000000000000..d81b210f9d77430328406254c9b16c73e15cc168 GIT binary patch literal 5992 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
- + +
@@ -52,7 +57,7 @@ import { ref, watch } from 'vue'; import { getIdUrl } from '@/api/mapModal'; import PdfView from '@/components/pdf/pdfView.vue'; - +import LiveVideoBox from '@/views/shiPinJianKong/components/LiveVideoBox.vue'; interface AttachmentFileItem { id: string; name: string; diff --git a/frontend/src/components/MapModal/components/NoLiveVideo.vue b/frontend/src/components/MapModal/components/NoLiveVideo.vue index 17b5eb60..2158f2f4 100644 --- a/frontend/src/components/MapModal/components/NoLiveVideo.vue +++ b/frontend/src/components/MapModal/components/NoLiveVideo.vue @@ -23,7 +23,7 @@ v-model:value="dateRange" format="YYYY-MM-DD" value-format="YYYY-MM-DD" - style="width: 100%" + style="width: 300px" @change="handleDateChange" /> @@ -281,7 +281,9 @@ watch( .video-mode { display: flex; - height: 600px; + height: 60vh; + min-height: 400px; + max-height: 800px; gap: 12px; .video-main { @@ -309,16 +311,24 @@ watch( flex-direction: column; border: 1px solid #e8e8e8; border-radius: 4px; + min-width: 0; .sidebar-search { padding: 8px; display: flex; align-items: center; border-bottom: 1px solid #e8e8e8; + flex-wrap: wrap; + gap: 8px; + + :deep(.ant-picker) { + max-width: 100%; + } } .sidebar-list { - height: 600px; + flex: 1; + min-height: 0; overflow-y: auto; display: grid; grid-template-columns: repeat(2, 1fr); @@ -339,13 +349,13 @@ watch( } &.active { - border-color: #1890ff; - background: #e6f7ff; + // border-color: #1890ff; + // background: #e6f7ff; } .item-thumb { width: 100%; - height: 105px; + height: 143px; background: #1a1a1a; overflow: hidden; display: flex; @@ -375,8 +385,8 @@ watch( .item-time { padding: 4px; - font-size: 11px; - color: #666; + font-size: 14px; + color: #000000D9; text-align: center; white-space: nowrap; overflow: hidden; @@ -393,4 +403,78 @@ watch( } } } + +// 响应式适配 +@media screen and (max-width: 1400px) { + .no-live-video { + .video-mode { + height: 55vh; + gap: 10px; + + .video-main { + flex: 0 0 65%; + } + + .video-sidebar { + flex: 0 0 35%; + + .sidebar-list { + grid-template-columns: repeat(2, 1fr); + gap: 6px; + padding: 6px; + } + } + } + } +} + +@media screen and (max-width: 1200px) { + .no-live-video { + .video-mode { + height: 50vh; + gap: 8px; + + .video-main { + flex: 0 0 70%; + } + + .video-sidebar { + flex: 0 0 30%; + + .sidebar-list { + grid-template-columns: 1fr; + } + + .sidebar-search { + :deep(.ant-picker-range) { + width: 100% !important; + } + } + } + } + } +} + +@media screen and (max-width: 768px) { + .no-live-video { + .video-mode { + flex-direction: column; + height: auto; + + .video-main { + flex: none; + height: 50vh; + } + + .video-sidebar { + flex: none; + height: 40vh; + + .sidebar-list { + grid-template-columns: repeat(2, 1fr); + } + } + } + } +} diff --git a/frontend/src/components/MapModal/index.vue b/frontend/src/components/MapModal/index.vue index 09e4f41e..3e974242 100644 --- a/frontend/src/components/MapModal/index.vue +++ b/frontend/src/components/MapModal/index.vue @@ -677,7 +677,7 @@ const setQGCTabList = async (_tabs: any, stcd: string) => { }; const res2 = await getVideoList(params); console.log('', modelStore.params.sttp); - // debugger + // if ( res2?.data?.data?.length > 0 || res2?.data?.records?.length > 0 || diff --git a/frontend/src/components/MapModal/setting.config.ts b/frontend/src/components/MapModal/setting.config.ts index ea097c15..aeea96a7 100644 --- a/frontend/src/components/MapModal/setting.config.ts +++ b/frontend/src/components/MapModal/setting.config.ts @@ -310,7 +310,9 @@ const FPTabs1: Array = [ name: '基础信息', key: 'basicInfo', type: 'basic', - url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo' + default: true, // 默认显示 + url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo', + }, { name: '实时视频', @@ -396,14 +398,14 @@ const FBTabs: Array = [ } } ] + }, + { + name: '实时视频', + key: 'videoInfo', + type: 'video', + url: '/video/dataStcdFrame/getVideoMonitorList' } // { - // name: '实时视频', - // key: 'videoInfo', - // type: 'video', - // url: '/video/dataStcdFrame/getVideoMonitorList' - // } - // { // name: "全景影像", // key: "panoramaInfo", // type: "panorama" @@ -873,7 +875,7 @@ const noLiveVideoTabs: Array = [ }, { name: '录像视频', - key: 'videoInfo', + key: 'noLiveVideo', type: 'noLiveVideo', url: '/video/dataStcdFrame/getVideoMonitorList' } diff --git a/frontend/src/components/SidePanelItem/index.vue b/frontend/src/components/SidePanelItem/index.vue index df4bbf5a..a464c85c 100644 --- a/frontend/src/components/SidePanelItem/index.vue +++ b/frontend/src/components/SidePanelItem/index.vue @@ -53,7 +53,12 @@ show-search placeholder="请选择" :size="'small'" - style="width: 120px" + :style="{ width: select.width || '80px' }" + :dropdown-style="{ + maxHeight: '400px', + overflow: 'auto', + minWidth: '200px' + }" :options="select.options" :filter-option="filterOption" @focus="handleFocus" @@ -84,7 +89,7 @@ value: 'value', children: 'children' }" - tree-node-filter-prop="label" + tree-node-filter-prop="title" popup-class-name="no-wrap-tree-select" @select="handleTreeSelect" @expand="handleTreeExpand" @@ -177,11 +182,12 @@ interface PromptConfig { } interface SelectConfig { - picker: any; - format: any; - show: boolean; - value: string | undefined; - options: SelectProps['options']; + picker?: any; + format?: any; + show?: boolean; + value?: string | undefined; + options?: SelectProps['options']; + width?: string; } // 定义组件名(便于调试和递归) @@ -239,7 +245,8 @@ const props = defineProps({ default: () => ({ show: false, value: undefined, - options: [] + options: [], + width: '' }) }, moreSelect: { @@ -652,7 +659,7 @@ const handleTreeSelect = (selectedKeys: string | string[], info: any) => { } moreSelectValue.value = selectedValue; - + // // 保存选中节点的额外属性(如 lgtd、lttd 等) if (info && typeof info === 'object') { selectedNodeExtra.value = { @@ -683,11 +690,16 @@ const handleFocus = () => { // Handle focus }; -const filterOption = (input: string, option?: { label: string; value: string }) => { +const filterOption = ( + input: string, + option?: { label: string; value: string } +) => { if (!option) return false; const label = option.label?.toLowerCase() || ''; const value = option.value?.toLowerCase() || ''; - return label.includes(input.toLowerCase()) || value.includes(input.toLowerCase()); + return ( + label.includes(input.toLowerCase()) || value.includes(input.toLowerCase()) + ); }; // 文字提示容器 @@ -759,7 +771,6 @@ const emitAllValues = () => { } else { payload.scopeDate = []; } - emit('update-values', payload); }; diff --git a/frontend/src/modules/EnvironmentalQuality/TwoLayers/EnvironmentalQualityTwoLayers.vue b/frontend/src/modules/EnvironmentalQuality/TwoLayers/EnvironmentalQualityTwoLayers.vue index ac7acf40..e871f270 100644 --- a/frontend/src/modules/EnvironmentalQuality/TwoLayers/EnvironmentalQualityTwoLayers.vue +++ b/frontend/src/modules/EnvironmentalQuality/TwoLayers/EnvironmentalQualityTwoLayers.vue @@ -596,7 +596,7 @@ const handleSearch = () => { // console.log( typeOne.value ) // console.log( formState.dtinType ) // console.log(typeOne.value == 'all' && formState.dtinType !='') - // debugger + // const filters: any[] = [ formState.dataDimensionVal != 'all' ? { field: 'baseId', @@ -660,7 +660,7 @@ const handleSearch = () => { // 刷新表格 tableRef.value?.getList(filter) if (kong.value) { - // debugger + // fetchPieData() } kong.value = true @@ -781,7 +781,7 @@ watch( () => props.typeOne, (newVal) => { typeOne.value = newVal - // debugger + // } ) @@ -798,7 +798,7 @@ watch( () => formState.types, (newType, oldType) => { if (!formState.dateValues || newType === oldType) return - // debugger + // const currentValue: any = formState.dateValues if (newType === 'year') { diff --git a/frontend/src/modules/EnvironmentalQuality/TwoLayers/HJMZDTwoLays.vue b/frontend/src/modules/EnvironmentalQuality/TwoLayers/HJMZDTwoLays.vue index 250a3217..d89fd1b2 100644 --- a/frontend/src/modules/EnvironmentalQuality/TwoLayers/HJMZDTwoLays.vue +++ b/frontend/src/modules/EnvironmentalQuality/TwoLayers/HJMZDTwoLays.vue @@ -564,7 +564,7 @@ watch( if (!stcd) { return; } - // debugger + // tableRef.value.tableData = []; getCol({ stcd, startTime, endTime }); }, diff --git a/frontend/src/modules/EnvironmentalQuality/index.vue b/frontend/src/modules/EnvironmentalQuality/index.vue index 2d3c4279..d2c9a511 100644 --- a/frontend/src/modules/EnvironmentalQuality/index.vue +++ b/frontend/src/modules/EnvironmentalQuality/index.vue @@ -319,7 +319,7 @@ const initChart = (): Promise => { const getEchartsData = async () => { // 1. 格式验证 const currentValue = datetimePicker.value.value; - // debugger + // if (select.value.value === 'year') { // 年度模式:验证是否为 YYYY 格式(4位数字) if (!/^\d{4}$/.test(currentValue)) { @@ -361,7 +361,7 @@ const getEchartsData = async () => { if( ! baseid.value){ return } - // debugger + // let params = { "filter": { "logic": "and", @@ -439,7 +439,7 @@ const getEchartsData = async () => { ] }; console.log('请求参数:', params); - // debugger + // // 4. 调用API并处理数据 loading.value = true; try { @@ -687,7 +687,7 @@ const updateChartData = (currentLabel: string, lastYearLabel: string) => { if (barData) { // 新增:获取对应的 baseid 或 rstcd const selectedId = chartDataIdMap.value[dataIndex] || ''; - // debugger + // clickedBarData.value = { name: barData.name.replace('\n', ''), // 去除换行符 current: barData.current, diff --git a/frontend/src/modules/GYZLLB/index.vue b/frontend/src/modules/GYZLLB/index.vue index fbc8e841..91f70884 100644 --- a/frontend/src/modules/GYZLLB/index.vue +++ b/frontend/src/modules/GYZLLB/index.vue @@ -714,7 +714,7 @@ const getechartsdata = async (yearOne: string) => { stopAutoPlay(); return; } - // debugger + // // 缓存全量数据 cachedApiData.value = responseData; currentYear.value = yearOne; diff --git a/frontend/src/modules/chuixiangshuiwenChangeMod/index.vue b/frontend/src/modules/chuixiangshuiwenChangeMod/index.vue index 0f04e34d..fb8619e4 100644 --- a/frontend/src/modules/chuixiangshuiwenChangeMod/index.vue +++ b/frontend/src/modules/chuixiangshuiwenChangeMod/index.vue @@ -37,7 +37,7 @@ import SidePanelItem from '@/components/SidePanelItem/index.vue'; import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent'; import { getChuiXiangShuiWenTreeStcd, getCxswList } from '@/api/sw'; import { useModelStore } from '@/store/modules/model'; -import { useMapModalStore } from '@/store/modules/mapModal'; +// import { useMapModalStore } from '@/store/modules/mapModal'; import { MapClass } from '@/components/gis/map.class'; const modelStore = useModelStore(); @@ -356,7 +356,6 @@ const selectOptions = async () => { const data = { filter, sort }; const res = await getChuiXiangShuiWenTreeStcd(data); let dataOne = res?.data?.data || res.data; - if (dataOne.length > 0) { const treeData = dataOne.map(item => { return { @@ -547,7 +546,7 @@ const initChart = () => { )}-${lastDay} 23:59:59`; console.log(endTime); modelStore.modalVisible = true; - modelStore.params.sttp = 'WT'; + modelStore.params.sttp = 'WTRV'; modelStore.params.enfc = '1'; modelStore.title = stnm; // modelStore.isBasicEdit = true; @@ -663,53 +662,53 @@ const updateChart = () => { chartInstance.setOption(option, { notMerge: true }); }; -const handleChartClick = (params: any) => { - if (!params || !params.seriesName) return; +// const handleChartClick = (params: any) => { +// if (!params || !params.seriesName) return; - const matchMonth = params.seriesName.match(/\d+/); - const monthNum = matchMonth ? parseInt(matchMonth[0]) : 1; +// const matchMonth = params.seriesName.match(/\d+/); +// const monthNum = matchMonth ? parseInt(matchMonth[0]) : 1; - const year = - typeof datetimePicker.value.value === 'string' - ? parseInt(datetimePicker.value.value) - : datetimePicker.value.value; +// const year = +// typeof datetimePicker.value.value === 'string' +// ? parseInt(datetimePicker.value.value) +// : datetimePicker.value.value; - const startTime = `${year}-${String(monthNum).padStart(2, '0')}-01 00:00:00`; - const lastDay = new Date(year, monthNum, 0).getDate(); - const endTime = `${year}-${String(monthNum).padStart( - 2, - '0' - )}-${lastDay} 23:59:59`; +// const startTime = `${year}-${String(monthNum).padStart(2, '0')}-01 00:00:00`; +// const lastDay = new Date(year, monthNum, 0).getDate(); +// const endTime = `${year}-${String(monthNum).padStart( +// 2, +// '0' +// )}-${lastDay} 23:59:59`; - const currentStcd = select.value.value; - let currentStnm = ''; +// const currentStcd = select.value.value; +// let currentStnm = ''; - select.value.options.forEach((station: any) => { - station.children?.forEach((child: any) => { - if (child.value === currentStcd) { - currentStnm = child.title; - } - }); - }); +// select.value.options.forEach((station: any) => { +// station.children?.forEach((child: any) => { +// if (child.value === currentStcd) { +// currentStnm = child.title; +// } +// }); +// }); - import('@/store/modules/model').then(({ useModelStore }) => { - import('@/components/MapModal/setting.config').then(({ handleTabs }) => { - const modelStore = useModelStore(); +// import('@/store/modules/model').then(({ useModelStore }) => { +// import('@/components/MapModal/setting.config').then(({ handleTabs }) => { +// const modelStore = useModelStore(); - modelStore.params = { - sttp: 'WT', - stcd: currentStcd, - titleName: currentStnm, - enfc: '1', - timeRange: [startTime, endTime] - } as any; +// modelStore.params = { +// sttp: 'WT', +// stcd: currentStcd, +// titleName: currentStnm, +// enfc: '1', +// timeRange: [startTime, endTime] +// } as any; - modelStore.title = currentStnm ? `${currentStnm} ` : ''; - modelStore.tabList = handleTabs(modelStore.params); - modelStore.modalVisible = true; - }); - }); -}; +// modelStore.title = currentStnm ? `${currentStnm} ` : ''; +// modelStore.tabList = handleTabs(modelStore.params); +// modelStore.modalVisible = true; +// }); +// }); +// }; // ==================== 生命周期和监听 ==================== @@ -750,19 +749,9 @@ watch( // }, // { deep: true } // ); -const handlePanelChange1 = (data: any, type: string) => { +const handlePanelChange1 = (data: any) => { console.log('当前所有控件状态:', data); if (data.moreSelect && data.datetime) { - if (type == 'click') { - const mapClass = MapClass.getInstance(); - mapClass.flyTopanto( - [ - Number(data.selectedNodeExtra.lgtd), - Number(data.selectedNodeExtra.lttd) - ], - 15 - ); - } year.value = data.datetime; fetchChartData(data.moreSelect, data.datetime); } else { @@ -772,6 +761,16 @@ const handlePanelChange1 = (data: any, type: string) => { selected.value = {}; showemit.value = false; } + if (data?.selectedNodeExtra?.lttd && data?.selectedNodeExtra?.lgtd) { + const mapClass = MapClass.getInstance(); + mapClass.flyTopanto( + [ + Number(data.selectedNodeExtra.lgtd), + Number(data.selectedNodeExtra.lttd) + ], + 15 + ); + } }; diff --git a/frontend/src/modules/churukushuiwenMod/index.vue b/frontend/src/modules/churukushuiwenMod/index.vue index 71ff0fb7..388895b7 100644 --- a/frontend/src/modules/churukushuiwenMod/index.vue +++ b/frontend/src/modules/churukushuiwenMod/index.vue @@ -52,6 +52,7 @@ import SidePanelItem from '@/components/SidePanelItem/index.vue'; import { getVmsstbprpt, inOutOneGetKendoListCust } from '@/api/sw'; import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent'; import churukushuiwen from './churukushuiwen.vue'; +import { MapClass } from '@/components/gis/map.class'; // ==================== 组件基础配置 ==================== // 定义组件名(便于调试和递归) defineOptions({ @@ -608,10 +609,12 @@ const handleModalClose = () => { */ const handlePanelChange1 = (data: any, type: string) => { // TODO: 后续可扩展联动逻辑 - if (data.moreSelect) { + if (data.moreSelect && data.scopeDate) { paramsOne.value.value = data.moreSelect; - } - if (type == 'click') { + paramsOne.value.tm = data.scopeDate; + fetchChartData(); + } + if (data?.selectedNodeExtra?.lttd && data?.selectedNodeExtra?.lgtd) { const mapClass = MapClass.getInstance(); mapClass.flyTopanto( [ @@ -621,8 +624,6 @@ const handlePanelChange1 = (data: any, type: string) => { 13 ); } - paramsOne.value.tm = data.scopeDate; - fetchChartData(); }; /** @@ -695,7 +696,6 @@ const getselsectData = async () => { console.log('res', res); const data = res?.data?.data || res?.data; const obj: any = {}; - if (data) { // 将扁平数据转换为树形结构(按基地分组) data.map(e => { @@ -733,7 +733,6 @@ const getselsectData = async () => { return indexA - indexB; }); console.log('treeData', treeData); - // 更新下拉框选项 select.value.options = treeData; diff --git a/frontend/src/modules/fishSurvey/FishChangeTu/index.vue b/frontend/src/modules/fishSurvey/FishChangeTu/index.vue new file mode 100644 index 00000000..b2c4c93f --- /dev/null +++ b/frontend/src/modules/fishSurvey/FishChangeTu/index.vue @@ -0,0 +1,338 @@ + + + + + diff --git a/frontend/src/modules/fishSurvey/FishIntroduce/index.vue b/frontend/src/modules/fishSurvey/FishIntroduce/index.vue index 220c21f7..e910b751 100644 --- a/frontend/src/modules/fishSurvey/FishIntroduce/index.vue +++ b/frontend/src/modules/fishSurvey/FishIntroduce/index.vue @@ -1,76 +1,98 @@ \ No newline at end of file + diff --git a/frontend/src/modules/fishSurvey/FishVideo/index.vue b/frontend/src/modules/fishSurvey/FishVideo/index.vue index 324687dd..7c4a9546 100644 --- a/frontend/src/modules/fishSurvey/FishVideo/index.vue +++ b/frontend/src/modules/fishSurvey/FishVideo/index.vue @@ -1,76 +1,144 @@ \ No newline at end of file + diff --git a/frontend/src/modules/fishSurvey/SurveyQingKuang/DeviceTableModal.vue b/frontend/src/modules/fishSurvey/SurveyQingKuang/DeviceTableModal.vue new file mode 100644 index 00000000..68e8558b --- /dev/null +++ b/frontend/src/modules/fishSurvey/SurveyQingKuang/DeviceTableModal.vue @@ -0,0 +1,407 @@ + + + + + diff --git a/frontend/src/modules/fishSurvey/SurveyQingKuang/index.vue b/frontend/src/modules/fishSurvey/SurveyQingKuang/index.vue new file mode 100644 index 00000000..a823e004 --- /dev/null +++ b/frontend/src/modules/fishSurvey/SurveyQingKuang/index.vue @@ -0,0 +1,177 @@ + + + + + diff --git a/frontend/src/modules/fishSurvey/ZhuanZhiIntroduce/index.vue b/frontend/src/modules/fishSurvey/ZhuanZhiIntroduce/index.vue index 24c07ee7..d2bca5f2 100644 --- a/frontend/src/modules/fishSurvey/ZhuanZhiIntroduce/index.vue +++ b/frontend/src/modules/fishSurvey/ZhuanZhiIntroduce/index.vue @@ -1,75 +1,111 @@ \ No newline at end of file + diff --git a/frontend/src/modules/guoyusheshijiansheqingkuang/ModalPage/index.vue b/frontend/src/modules/guoyusheshijiansheqingkuang/ModalPage/index.vue index 3806a835..aec41654 100644 --- a/frontend/src/modules/guoyusheshijiansheqingkuang/ModalPage/index.vue +++ b/frontend/src/modules/guoyusheshijiansheqingkuang/ModalPage/index.vue @@ -308,7 +308,7 @@ const buildFilter = () => { // 处理排序变化 const handleSortChange = (info: { field: string; order: string | null }) => { - // debugger + // if (info.field && info.order) { sortState.value = info; } else { @@ -356,6 +356,8 @@ const handleViewDetail = (record: any, type: string) => { modelStore.params.sttp = lastValue modelStore.title = record.stnm; modelStore.params.stcd = record.stcd; + modelStore.params.bldsttCcode = record.bldsttCcode; + // } // console.log('【查看详情】', record) }; diff --git a/frontend/src/modules/qixidiliuliangbianhua/index.vue b/frontend/src/modules/qixidiliuliangbianhua/index.vue index cb30c56f..8fff3e8e 100644 --- a/frontend/src/modules/qixidiliuliangbianhua/index.vue +++ b/frontend/src/modules/qixidiliuliangbianhua/index.vue @@ -609,13 +609,13 @@ const getselsectData = async () => { value: item.stcd }; }); - // debugger + // }; const convertDateRange = (dateRange: string[]) => { if (!dateRange || dateRange.length !== 2) { return null; } - // debugger + // const [startStr, endStr] = dateRange; diff --git a/frontend/src/modules/qixidishuiwenbianhua/index.vue b/frontend/src/modules/qixidishuiwenbianhua/index.vue index 42cb222a..08100bb2 100644 --- a/frontend/src/modules/qixidishuiwenbianhua/index.vue +++ b/frontend/src/modules/qixidishuiwenbianhua/index.vue @@ -514,7 +514,7 @@ const convertDateRange = (dateRange: string[]) => { if (!dateRange || dateRange.length !== 2) { return null; } - // debugger + // const [startStr, endStr] = dateRange; @@ -634,7 +634,7 @@ const getselsectData = async () => { value: item.stcd }; }); - // debugger + // }; //// watch( diff --git a/frontend/src/modules/shengTaiLiuLiangXieFangSheShiMod/xianZhiYanChenBianHua/index.vue b/frontend/src/modules/shengTaiLiuLiangXieFangSheShiMod/xianZhiYanChenBianHua/index.vue index b1e98f89..2de69007 100644 --- a/frontend/src/modules/shengTaiLiuLiangXieFangSheShiMod/xianZhiYanChenBianHua/index.vue +++ b/frontend/src/modules/shengTaiLiuLiangXieFangSheShiMod/xianZhiYanChenBianHua/index.vue @@ -170,7 +170,7 @@ const chartRef = ref(); // 处理图表点击事件 const handleChartClick = (params: any) => { - // debugger + // console.log('点击数据点:', params); const { name, value, data } = params; modelStore.modalVisible = true; diff --git a/frontend/src/modules/shengTaiLiuLiangXieFangSheShiMod/xieFangFenBu/index.vue b/frontend/src/modules/shengTaiLiuLiangXieFangSheShiMod/xieFangFenBu/index.vue index 7245ee49..30ae4cb3 100644 --- a/frontend/src/modules/shengTaiLiuLiangXieFangSheShiMod/xieFangFenBu/index.vue +++ b/frontend/src/modules/shengTaiLiuLiangXieFangSheShiMod/xieFangFenBu/index.vue @@ -404,7 +404,7 @@ const fetchData = async () => { }); data.value = processedData; - // debugger + // // 提取唯一的基地名称作为 X 轴数据 echartsXData.value = [ ...new Set(processedData.map(item => item.basename)) diff --git a/frontend/src/modules/shengtaidabiaoMod/TwoLayer/ShengTaiLiuLiangDaBQKTwoLayer.vue b/frontend/src/modules/shengtaidabiaoMod/TwoLayer/ShengTaiLiuLiangDaBQKTwoLayer.vue index a7921bb2..1791ddf0 100644 --- a/frontend/src/modules/shengtaidabiaoMod/TwoLayer/ShengTaiLiuLiangDaBQKTwoLayer.vue +++ b/frontend/src/modules/shengtaidabiaoMod/TwoLayer/ShengTaiLiuLiangDaBQKTwoLayer.vue @@ -37,6 +37,7 @@ :allow-clear="false" format="YYYY-MM-DD" style="width: 260px" + :presets="DateSetting.RangeButton.days1" /> @@ -103,7 +104,7 @@ import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent'; import { dayGetKendoListCust, hourGetKendoListCust } from '@/api/stll'; import BasicTable from '@/components/BasicTable/index.vue'; import { useModelStore } from '@/store/modules/model'; - +import { DateSetting } from '@/utils/enumeration'; const modelStore = useModelStore(); const props = defineProps<{ options?: any[]; diff --git a/frontend/src/modules/shengtaidabiaoMod/index.vue b/frontend/src/modules/shengtaidabiaoMod/index.vue index 7cdf61dc..5c9c4353 100644 --- a/frontend/src/modules/shengtaidabiaoMod/index.vue +++ b/frontend/src/modules/shengtaidabiaoMod/index.vue @@ -244,7 +244,7 @@ const getData = async () => { // 根据API响应结构规范处理数据 if (res.data && res.data.list) { const apiList = res.data.list; - // debugger + // // 只使用前两条数据(type: 1 和 type: 2) if (apiList && apiList.length > 0) { dataArr.value = apiList.slice(0, 2).map((item: any) => ({ @@ -311,7 +311,7 @@ const getcont = async () => { if (list) { titleData.value = list } - // debugger + // }; // 页面加载时执行的逻辑 onMounted(() => { diff --git a/frontend/src/modules/shengtaidabiaoTwoMod/index.vue b/frontend/src/modules/shengtaidabiaoTwoMod/index.vue index f384b4f0..dd15352e 100644 --- a/frontend/src/modules/shengtaidabiaoTwoMod/index.vue +++ b/frontend/src/modules/shengtaidabiaoTwoMod/index.vue @@ -307,7 +307,7 @@ const initChart = () => { const handleChartClick = (params: any) => { const categoryName = params.name; const currentIndex = params.dataIndex; - // debugger + // // 设置弹框标题 detailModalTitle.value = @@ -318,7 +318,7 @@ const handleChartClick = (params: any) => { // 获取当前点击项的详细数据 const baseId = mode.value === 'top' ? chartData.value.baseIds[currentIndex] : undefined; const qecPerformance = mode.value === 'left' ? chartData.value.qecPerformances[currentIndex] : undefined; - // debugger + // const currentItem = { baseId: baseId, @@ -505,7 +505,7 @@ const getcont = async () => { if (list) { titleData.value = list; } - // debugger + // }; // 页面加载时执行的逻辑 onMounted(() => { diff --git a/frontend/src/modules/shuiWenNianNeiFenBu/index.vue b/frontend/src/modules/shuiWenNianNeiFenBu/index.vue index 42ec49b6..adec0042 100644 --- a/frontend/src/modules/shuiWenNianNeiFenBu/index.vue +++ b/frontend/src/modules/shuiWenNianNeiFenBu/index.vue @@ -224,6 +224,7 @@ const getselectData = async () => { // 合并结果并设置选项 select.value.options = [...dataMapNameArr, ...otherArr]; + // // if (baseid.value == 'all') { // select.value.value = '008640202300001021' @@ -536,23 +537,23 @@ onBeforeUnmount(() => { //监听子组件的数据变化 const handlePanelChange1 = (data: any, type: string) => { console.log('当前所有控件状态:', data); - if (type == 'click') { + // 当选择器或日期变化时,重新加载图表数据 + if (data.moreSelect || data.datetime) { + select.value.value = data.moreSelect; + datetimePicker.value.value = data.datetime; + // + getshuiwenList(); + } + if (data?.selectedNodeExtra?.lttd && data?.selectedNodeExtra?.lgtd) { const mapClass = MapClass.getInstance(); mapClass.flyTopanto( [ Number(data.selectedNodeExtra.lgtd), Number(data.selectedNodeExtra.lttd) ], - 15 + 15 ); } - // 当选择器或日期变化时,重新加载图表数据 - if (data.moreSelect || data.datetime) { - select.value.value = data.moreSelect; - datetimePicker.value.value = data.datetime; - // debugger - getshuiwenList(); - } }; const baseid = ref(''); watch( diff --git a/frontend/src/modules/shuizhijiancegongzuoQK/index.vue b/frontend/src/modules/shuizhijiancegongzuoQK/index.vue index 6732ea46..d655156f 100644 --- a/frontend/src/modules/shuizhijiancegongzuoQK/index.vue +++ b/frontend/src/modules/shuizhijiancegongzuoQK/index.vue @@ -208,7 +208,7 @@ const getDataList = async () => { } // const params = [data1, data2] const res1 = await msstbprptGetKendoList(data1); - // debugger + // let finalData = facilities.value.map((item) => ({ ...item, count: 0 })) if (res1.data) { const { data } = res1 @@ -220,7 +220,7 @@ const getDataList = async () => { }) } console.log(finalData) - // debugger/ + // / const res2 = await msstbprptGetKendoList(data2); if (res2.data) { const responseData = res2?.data?.data @@ -231,7 +231,7 @@ const getDataList = async () => { } facilities.value = finalData console.log(finalData) - // debugger + // } catch (error) { console.error('获取数据失败:', error); } finally { diff --git a/frontend/src/modules/stllyanchengChangeMod/index.vue b/frontend/src/modules/stllyanchengChangeMod/index.vue index a8882c91..905d6795 100644 --- a/frontend/src/modules/stllyanchengChangeMod/index.vue +++ b/frontend/src/modules/stllyanchengChangeMod/index.vue @@ -166,7 +166,7 @@ const getSelect = async () => { } if (data && data.length > 0) { - // debugger; + // ; select.value.value = data[0].wbsCode; selectData.value = data[0].wbsCode; // 同步选中第一个 select.value.options = data.map(item => ({ diff --git a/frontend/src/store/modules/model.ts b/frontend/src/store/modules/model.ts index 58cc6681..38fe7274 100644 --- a/frontend/src/store/modules/model.ts +++ b/frontend/src/store/modules/model.ts @@ -34,6 +34,7 @@ export const useModelStore = defineStore('model', () => { sttpMap?: string; // 新增:站点类型映射 dtinType?: string; bldstt: string; + bldsttCcode: string; }>({ sttp: 'eng', stcd: '', @@ -45,7 +46,8 @@ export const useModelStore = defineStore('model', () => { sttpCode: '', sttpMap: '', dtinType: '', - bldstt: '' + bldstt: '', + bldsttCcode:'' }); const filter = ref({ stllgzlx: '', // 生态流量 - 规则类型 diff --git a/frontend/src/views/fish-survey/fishSurveyZhuanZhi.vue b/frontend/src/views/fish-survey/fishSurveyZhuanZhi.vue index 527d7a48..040cfe26 100644 --- a/frontend/src/views/fish-survey/fishSurveyZhuanZhi.vue +++ b/frontend/src/views/fish-survey/fishSurveyZhuanZhi.vue @@ -1,9 +1,73 @@ - + diff --git a/frontend/src/views/shiPinJianKong/components/LiveVideoBox.vue b/frontend/src/views/shiPinJianKong/components/LiveVideoBox.vue index a038dcf4..269ba916 100644 --- a/frontend/src/views/shiPinJianKong/components/LiveVideoBox.vue +++ b/frontend/src/views/shiPinJianKong/components/LiveVideoBox.vue @@ -14,6 +14,13 @@
+ +
+
+ +
数据源错误,无法加载视频
+
+
@@ -31,6 +38,9 @@ import videojs from 'video.js'; import 'video.js/dist/video-js.css'; const baseUrl = import.meta.env.VITE_APP_ATTACHMENT_URL; +// 错误提示显示状态 +const showError = ref(false); + // 注册 HLS 支持(video.js 8.x 内置了 HLS 支持) interface VideoData { @@ -89,6 +99,11 @@ const initPlayer = () => { player.dispose(); player = null; } + + // 重试计数器(用于限制重试次数) + let retryCount = 0; + const maxRetries = 5; + try { // 创建 video 元素 const videoElement = document.createElement('video'); @@ -195,36 +210,55 @@ const initPlayer = () => { const error = player.error(); console.error('播放器错误:', error); - // 保持最后一帧画面,不显示错误提示 - // 在后台静默重试 - let retryCount = 0; - const maxRetries = 10; + // 检查是否已达到最大重试次数 + if (retryCount >= maxRetries) { + console.warn(`已达到最大重试次数(${maxRetries}次),停止重试`); + // 显示自定义错误提示层 + showError.value = true; + return; + } - const attemptReload = () => { - if (retryCount < maxRetries && player && videoUrl.value) { - retryCount++; - setTimeout(() => { - try { - player.src({ - src: videoUrl.value, - type: videoType // 指定视频类型 - }); - player.load(); - player.play(); - } catch (e) { - if (retryCount < maxRetries) { - attemptReload(); + // 增加重试计数 + retryCount++; + console.log(`视频加载失败,正在进行第 ${retryCount}/${maxRetries} 次重试...`); + + // 立即显示自定义错误提示层 + showError.value = true; + + // 延迟后重试 + setTimeout(() => { + try { + if (player && videoUrl.value) { + // 隐藏错误提示层(重试时) + showError.value = false; + player.src({ + src: videoUrl.value, + type: videoType + }); + player.load(); + player.play(); + } + } catch (e) { + console.error('重试加载视频失败:', e); + // 如果重试失败且未达到最大次数,继续重试 + if (retryCount < maxRetries) { + setTimeout(() => { + if (player) { + player.error(); // 触发下一次错误处理 } - } - }, 3000); + }, 100); + } } - }; - - attemptReload(); + }, 3000); }); // 监听加载完成 - player.on('loadeddata', () => {}); + player.on('loadeddata', () => { + // 加载成功时重置重试计数器 + retryCount = 0; + // 隐藏错误提示 + showError.value = false; + }); // 监听播放状态 player.on('play', () => {}); @@ -339,6 +373,40 @@ onUnmounted(() => { } } + .custom-error-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0); + display: flex; + align-items: center; + justify-content: center; + z-index: 10; + + .error-content { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + + .error-icon { + font-size: 48px; + margin-bottom: 12px; + opacity: 0.5; + color: #999; + } + + .error-text { + font-size: 14px; + color: #fff; + text-align: center; + margin-top: 12px; + } + } + } + .video-empty { width: 100%; height: 100%; diff --git a/frontend/src/views/shuiZhiJianCe/shuiHuanJingZhiLiangZhuangKuang.vue b/frontend/src/views/shuiZhiJianCe/shuiHuanJingZhiLiangZhuangKuang.vue index 33661117..00b92a16 100644 --- a/frontend/src/views/shuiZhiJianCe/shuiHuanJingZhiLiangZhuangKuang.vue +++ b/frontend/src/views/shuiZhiJianCe/shuiHuanJingZhiLiangZhuangKuang.vue @@ -12,7 +12,7 @@ watch( () => JidiSelectEventStore.selectedItem, (newVal) => { console.log(newVal); - // debugger + // wbsCode.value = newVal.wbsCode; }, { deep: true, immediate: true } From 19d16a962bcacab0f8da6eb0ede088b9d0905960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=85=B4=E5=87=AF?= <2448379534@qq.com> Date: Thu, 18 Jun 2026 09:32:37 +0800 Subject: [PATCH 10/51] =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=9B=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.env.development | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/.env.development b/frontend/.env.development index 6f8bd729..5094aad0 100644 --- a/frontend/.env.development +++ b/frontend/.env.development @@ -12,7 +12,7 @@ VITE_APP_BASE_URL = 'http://10.84.121.127:8093' # VITE_APP_BASE_URL = 'http://172.16.21.142:8093' # VITE_APP_BASE_URL = 'http://172.16.21.142:8096' # 汤伟 -# VITE_APP_BASE_URL = 'http://10.84.121.21:8093' +VITE_APP_BASE_URL = 'http://10.84.121.127:8093' # VITE_APP_BASE_URL = 'http://192.168.1.162:8093' # 测试环境线上10.84.121.122: From d42040b13385261ad1242af93985d7cc5b11c942 Mon Sep 17 00:00:00 2001 From: tangwei Date: Thu, 18 Jun 2026 09:45:06 +0800 Subject: [PATCH 11/51] =?UTF-8?q?feat:=20=E6=B2=BF=E7=A8=8B=E7=94=9F?= =?UTF-8?q?=E6=80=81=E6=B5=81=E9=87=8F=E9=99=90=E5=80=BC=E5=8F=98=E5=8C=96?= =?UTF-8?q?=E6=9B=B2=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eq/controller/EngEqDataController.java | 11 + .../eq/entity/vo/EngEqLimitQueryVo.java | 20 ++ .../qgc_eng/eq/entity/vo/EngEqLimitVo.java | 28 +++ .../qgc_eng/eq/service/EngEqDataService.java | 6 + .../eq/service/impl/EngEqDataServiceImpl.java | 210 ++++++++++++++++++ 5 files changed, 275 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqLimitQueryVo.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqLimitVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java index 64e9c879..db724237 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java @@ -6,6 +6,8 @@ import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.config.ResponseResult; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDrtpDataVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqIntervalVo; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqLimitQueryVo; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqLimitVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqMsstbprptVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRuleVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqVmsstbprptVo; @@ -22,6 +24,8 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.List; + @RestController @RequestMapping("/eq") @Tag(name = "电站实时数据查询") @@ -87,6 +91,13 @@ public class EngEqDataController { return ResponseResult.successData(engEqDataService.getQgcHourVAlongKendoListCust(dataSourceRequest)); } + @PostMapping("/engalong/statistics/qgc/getEngLimit") + @Operation(summary = "沿程生态流量限值变化曲线") + public ResponseResult getQgcEngLimit(@RequestBody EngEqLimitQueryVo queryVo) { + List result = engEqDataService.getQgcEngLimit(queryVo); + return ResponseResult.successData(result); + } + @PostMapping("/fid/GetKendoListCust") @Operation(summary = "查询电站相关鱼类附件编码") public ResponseResult getFidKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqLimitQueryVo.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqLimitQueryVo.java new file mode 100644 index 00000000..f9985176 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqLimitQueryVo.java @@ -0,0 +1,20 @@ +package com.yfd.platform.qgc_eng.eq.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 EngEqLimitQueryVo { + + @Schema(description = "查询日期,支持 yyyy-MM-dd、yyyy-MM-dd HH:mm、yyyy-MM-dd HH:mm:ss") + private String date; + + @Schema(description = "基地编码") + private String baseId; + + @Schema(description = "流域编码") + private String rvcd; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqLimitVo.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqLimitVo.java new file mode 100644 index 00000000..f0083108 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqLimitVo.java @@ -0,0 +1,28 @@ +package com.yfd.platform.qgc_eng.eq.entity.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; +import java.util.Date; + +@Data +@Accessors(chain = true) +@Schema(description = "沿程生态流量限值") +public class EngEqLimitVo { + + @Schema(description = "电站编码") + private String stcd; + + @Schema(description = "电站名称") + private String stnm; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Schema(description = "查询日期") + private Date date; + + @Schema(description = "生态流量限值") + private BigDecimal qecLimit; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java index e68b0699..729bf403 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java @@ -7,6 +7,8 @@ import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDrtpDataVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDayIntervalVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqHourIntervalVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqIntervalVo; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqLimitQueryVo; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqLimitVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqMsstbprptVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRuleVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngQecAlongVo; @@ -16,6 +18,8 @@ import com.yfd.platform.qgc_eng.eq.entity.vo.QgcQecStaticVo; import com.yfd.platform.qgc_eng.eq.entity.vo.SdEqMonitorCountVo; import com.yfd.platform.qgc_eng.eq.entity.vo.WbsbVo; +import java.util.List; + public interface EngEqDataService { DataSourceResult getKendoListCust(DataSourceRequest dataSourceRequest); @@ -34,6 +38,8 @@ public interface EngEqDataService { DataSourceResult getQgcHourVAlongKendoListCust(DataSourceRequest dataSourceRequest); + List getQgcEngLimit(EngEqLimitQueryVo queryVo); + DataSourceResult getFidKendoListCust(DataSourceRequest dataSourceRequest); EngEqRuleVo getEngLimit(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java index 5f898876..ce289df7 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java @@ -16,6 +16,8 @@ import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDataVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDayDataVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDrtpDataVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDayIntervalVo; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqLimitQueryVo; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqLimitVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngFidVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqHourIntervalVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqIntervalVo; @@ -46,6 +48,7 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.ZoneId; import java.time.format.DateTimeFormatter; @Service @@ -380,6 +383,56 @@ public class EngEqDataServiceImpl implements EngEqDataService { return result; } + @Override + public List getQgcEngLimit(EngEqLimitQueryVo queryVo) { + if (queryVo == null || StrUtil.isBlank(queryVo.getDate())) { + throw new IllegalArgumentException("查询日期不能为空."); + } + Date queryDate = parseEngLimitQueryDate(queryVo.getDate()); + if (queryDate == null) { + throw new IllegalArgumentException("查询日期格式不正确."); + } + + String baseId = StrUtil.trimToNull(queryVo.getBaseId()); + String rvcd = StrUtil.trimToNull(queryVo.getRvcd()); + Map paramMap = new HashMap<>(); + paramMap.put("queryDate", formatDateTime(queryDate)); + if (StrUtil.isNotBlank(baseId)) { + paramMap.put("baseId", baseId); + } + if (StrUtil.isNotBlank(rvcd)) { + paramMap.put("rvcd", rvcd); + } + + List stationList = microservicDynamicSQLMapper.getAllListWithResultType( + buildQgcEngLimitStationSql(baseId, rvcd), + paramMap, + EngEqLimitVo.class + ); + if (CollUtil.isEmpty(stationList)) { + return new ArrayList<>(); + } + + List> ruleRows = microservicDynamicSQLMapper.pageAllList( + null, + buildQgcEngLimitRuleSql(baseId, rvcd), + paramMap + ); + Map>> stationRuleMap = new HashMap<>(); + for (Map row : ruleRows) { + String stcd = asString(row.get("STCD")); + if (StrUtil.isBlank(stcd)) { + continue; + } + stationRuleMap.computeIfAbsent(stcd, key -> new ArrayList<>()).add(row); + } + for (EngEqLimitVo station : stationList) { + station.setDate(queryDate); + station.setQecLimit(resolveQgcEngLimitValue(queryDate, stationRuleMap.get(station.getStcd()))); + } + return stationList; + } + @Override public EngEqRuleVo getEngLimit(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); @@ -1278,6 +1331,55 @@ public class EngEqDataServiceImpl implements EngEqDataService { return sql.toString(); } + private String buildQgcEngLimitStationScopeSql(String baseId, String rvcd) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT det.STCD AS stcd, eng.ENNM AS stnm, along.ORDER_INDEX AS rvcdSort, det.SORT AS stcdSort ") + .append("FROM MS_ALONG_B along ") + .append("INNER JOIN MS_ALONGDET_B det ON along.ID = det.ALONG_ID ") + .append("INNER JOIN SD_ENGINFO_B_H eng ON eng.STCD = det.STCD ") + .append("WHERE det.STTP = 'ENG' ") + .append(" AND NVL(eng.IS_DELETED, 0) = 0 ") + .append(" AND NVL(eng.BLDSTT_CODE, 0) = 2 ") + .append(" AND along.CODE = 'common' ") + .append(" AND NVL(along.IS_DELETED, 0) = 0 ") + .append(" AND NVL(det.IS_DELETED, 0) = 0 "); + if (StrUtil.isNotBlank(baseId)) { + sql.append(" AND along.RVCD IN (") + .append("SELECT dic.HBRVCD FROM SD_HBRV_DIC dic ") + .append("WHERE dic.BASEID = #{map.baseId} ") + .append(" AND NVL(dic.IS_DELETED, 0) = 0 ") + .append(" AND NVL(dic.ENABLED, 1) = 1") + .append(") "); + } + if (StrUtil.isNotBlank(rvcd)) { + sql.append(" AND along.RVCD = #{map.rvcd} "); + } + return sql.toString(); + } + + private String buildQgcEngLimitStationSql(String baseId, String rvcd) { + return "SELECT scope.STCD AS stcd, scope.STNM AS stnm " + + "FROM (" + buildQgcEngLimitStationScopeSql(baseId, rvcd) + ") scope " + + "ORDER BY scope.RVCDSORT, scope.STCDSORT"; + } + + private String buildQgcEngLimitRuleSql(String baseId, String rvcd) { + return "SELECT scope.STCD AS stcd, det.TM AS tm, det.MIN_VAL AS minVal, " + + "det.BEGIN_TIME AS beginTime, det.END_TIME AS endTime " + + "FROM (" + buildQgcEngLimitStationScopeSql(baseId, rvcd) + ") scope " + + "INNER JOIN MS_WARN_RULE_STBPRP_B rel ON rel.STCD = scope.STCD " + + " AND NVL(rel.IS_DELETED, 0) = 0 " + + "INNER JOIN MS_WARN_RULE_B rule ON rule.ID = rel.RULE_ID " + + " AND rule.RULE_TYPE = 'EQMN' " + + " AND NVL(rule.IS_DELETED, 0) = 0 " + + "INNER JOIN MS_WARN_RULE_DETAIL_B det ON det.RULE_ID = rule.ID " + + " AND NVL(det.IS_DELETED, 0) = 0 " + + "WHERE det.TM <= TO_DATE(#{map.queryDate}, 'YYYY-MM-DD HH24:MI:SS') " + + " AND det.MIN_VAL IS NOT NULL " + + "ORDER BY scope.STCD, det.TM DESC, LPAD(det.BEGIN_TIME, 4, '0') DESC NULLS LAST, " + + " LPAD(det.END_TIME, 4, '0') DESC NULLS LAST"; + } + private List> queryEngLimitRuleDetails(String stcd, String startTime, String endTime, @@ -1338,6 +1440,100 @@ public class EngEqDataServiceImpl implements EngEqDataService { return prefix + String.join(";", parts); } + private BigDecimal resolveQgcEngLimitValue(Date queryDate, List> ruleRows) { + if (queryDate == null || CollUtil.isEmpty(ruleRows)) { + return null; + } + Date currentTm = null; + List> currentRows = new ArrayList<>(); + String monthDay = DateTimeFormatter.ofPattern("MMdd").format( + queryDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate() + ); + for (Map row : ruleRows) { + Date tm = toDate(row.get("TM")); + if (tm == null || queryDate.compareTo(tm) < 0) { + continue; + } + if (currentTm != null && !currentTm.equals(tm)) { + return matchQgcEngLimitValue(monthDay, currentRows); + } + currentTm = tm; + currentRows.add(row); + } + if (currentTm == null) { + return null; + } + return matchQgcEngLimitValue(monthDay, currentRows); + } + + private BigDecimal matchQgcEngLimitValue(String monthDay, List> ruleRows) { + BigDecimal defaultValue = null; + for (Map row : ruleRows) { + BigDecimal minVal = toBigDecimal(row.get("MINVAL")); + if (minVal == null) { + continue; + } + String beginTime = normalizeMonthDay(asString(row.get("BEGINTIME"))); + String endTime = normalizeMonthDay(asString(row.get("ENDTIME"))); + if (StrUtil.isNotBlank(beginTime) && StrUtil.isNotBlank(endTime)) { + if (isMonthDayInRange(monthDay, beginTime, endTime)) { + return minVal; + } + continue; + } + if (StrUtil.isBlank(beginTime) && StrUtil.isBlank(endTime)) { + defaultValue = minVal; + } + } + return defaultValue; + } + + private boolean isMonthDayInRange(String monthDay, String beginTime, String endTime) { + if (StrUtil.hasBlank(monthDay, beginTime, endTime)) { + return false; + } + return monthDay.compareTo(beginTime) >= 0 && monthDay.compareTo(endTime) <= 0; + } + + private String normalizeMonthDay(String value) { + String text = StrUtil.trimToNull(value); + if (text == null) { + return null; + } + return StrUtil.padPre(text, 4, '0'); + } + + private Date parseEngLimitQueryDate(String text) { + String value = StrUtil.trimToNull(text); + if (value == null) { + return null; + } + value = value.replace('T', ' '); + try { + if (value.length() == 10) { + LocalDate localDate = LocalDate.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd")); + return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + } + if (value.length() == 16) { + LocalDateTime localDateTime = LocalDateTime.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")); + return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); + } + LocalDateTime localDateTime = LocalDateTime.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); + } catch (Exception ex) { + return null; + } + } + + private String formatDateTime(Date date) { + if (date == null) { + return null; + } + return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format( + date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime() + ); + } + private String buildHourIntervalViewSql(DataSourceRequest.FilterDescriptor filter, Map paramMap, int[] indexHolder) { @@ -4306,6 +4502,20 @@ public class EngEqDataServiceImpl implements EngEqDataService { return new BigDecimal(String.valueOf(value)); } + private Date toDate(Object value) { + if (value == null) { + return null; + } + if (value instanceof Date date) { + return date; + } + String text = StrUtil.trimToNull(String.valueOf(value)); + if (text == null) { + return null; + } + return parseEngLimitQueryDate(text); + } + private String stripTrailingZeros(BigDecimal value) { if (value == null) { return null; From eea7aa8213d6a23c3b5d24c7c91ed4b92f9f4e55 Mon Sep 17 00:00:00 2001 From: tangwei Date: Thu, 18 Jun 2026 14:21:28 +0800 Subject: [PATCH 12/51] =?UTF-8?q?feat:=20=E7=94=9F=E6=80=81=E6=B5=81?= =?UTF-8?q?=E9=87=8F=E6=B3=84=E6=94=BE=E8=AE=BE=E6=96=BD=E5=9F=BA=E7=A1=80?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eq/controller/EngEqDataController.java | 8 + .../eq/entity/vo/EngEqBaseMsstbprptVo.java | 77 +++++ .../qgc_eng/eq/service/EngEqDataService.java | 3 + .../eq/service/impl/EngEqDataServiceImpl.java | 291 ++++++++++++++++++ 4 files changed, 379 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqBaseMsstbprptVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java index db724237..abff7d48 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java @@ -4,6 +4,7 @@ import com.yfd.platform.common.DataSourceLoadOptionsBase; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqBaseMsstbprptVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDrtpDataVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqIntervalVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqLimitQueryVo; @@ -73,6 +74,13 @@ public class EngEqDataController { return ResponseResult.successData(result); } + @PostMapping("/base/msstbprpt/GetKendoList") + @Operation(summary = "生态流量泄放设施基础信息查询") + public ResponseResult getBaseMsstbprptList(@RequestBody DataSourceRequest dataSourceRequest) { + DataSourceResult result = engEqDataService.getBaseMsstbprptList(dataSourceRequest); + return ResponseResult.successData(result); + } + @PostMapping("/interval/qgc/hour/GetKendoListCust") @Operation(summary = "生态流量达标率小时统计(二级页面)") public ResponseResult getQgcHourKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqBaseMsstbprptVo.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqBaseMsstbprptVo.java new file mode 100644 index 00000000..e90510ac --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqBaseMsstbprptVo.java @@ -0,0 +1,77 @@ +package com.yfd.platform.qgc_eng.eq.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +@Data +@Schema(description = "生态流量泄放设施基础信息查询") +public class EngEqBaseMsstbprptVo implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "设施编码") + private String stcd; + + @Schema(description = "设施名称") + private String stnm; + + @Schema(description = "设施类型编码") + private String sttpCode; + + @Schema(description = "设施类型名称") + private String sttpName; + + @Schema(description = "所属电站编码") + private String rstcd; + + @Schema(description = "所属电站名称") + private String rstcdName; + + @Schema(description = "基地编码") + private String baseId; + + @Schema(description = "基地名称") + private String baseName; + + @Schema(description = "基地流域编码") + private String hbrvcd; + + @Schema(description = "基地流域名称") + private String hbrvcdName; + + @Schema(description = "设施位置") + private String stlc; + + @Schema(description = "经度") + private Double lgtd; + + @Schema(description = "纬度") + private Double lttd; + + @Schema(description = "高程") + private Double elev; + + @Schema(description = "建设状态分类编码") + private Integer bldsttCode; + + @Schema(description = "建设状态分类名称") + private String bldsttCodeName; + + @Schema(description = "数据接入状态") + private Integer dtin; + + @Schema(description = "数据接入状态中文") + private String dtinName; + + @Schema(description = "数据接入时间") + private Date dtinTm; + + @Schema(description = "数据时间") + private Date tm; + + @Schema(description = "排序") + private Integer orderIndex; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java index 729bf403..e1541b32 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java @@ -2,6 +2,7 @@ package com.yfd.platform.qgc_eng.eq.service; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqBaseMsstbprptVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDayDataVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDrtpDataVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDayIntervalVo; @@ -32,6 +33,8 @@ public interface EngEqDataService { DataSourceResult getMsstbprptList(DataSourceRequest dataSourceRequest); + DataSourceResult getBaseMsstbprptList(DataSourceRequest dataSourceRequest); + DataSourceResult getQgcHourKendoListCust(DataSourceRequest dataSourceRequest); DataSourceResult getQgcDayKendoListCust(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java index ce289df7..bb83777e 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java @@ -12,6 +12,7 @@ import com.yfd.platform.common.GroupingInfo; import com.yfd.platform.common.MicroservicDynamicSQLMapper; import com.yfd.platform.common.enums.QecIntervalEnum; import com.yfd.platform.common.enums.ShowEnum; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqBaseMsstbprptVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDataVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDayDataVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDrtpDataVo; @@ -102,6 +103,194 @@ public class EngEqDataServiceImpl implements EngEqDataService { return queryMsstbprptGroupList(dataSourceRequest, loadOptions); } + @Override + public DataSourceResult getBaseMsstbprptList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + if (CollUtil.isEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) { + return queryBaseMsstbprptDetailList(dataSourceRequest, loadOptions); + } + return queryBaseMsstbprptGroupList(dataSourceRequest, loadOptions); + } + + private DataSourceResult queryBaseMsstbprptDetailList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(buildBaseMsstbprptDetailSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect())) + .append(" FROM (") + .append(buildBaseMsstbprptViewSql()) + .append(") t WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = buildBaseMsstbprptFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0}); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + sql.append(buildBaseMsstbprptDetailOrderBySql(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, EngEqBaseMsstbprptVo.class); + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private DataSourceResult queryBaseMsstbprptGroupList(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 = mapBaseMsstbprptColumn(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 = mapBaseMsstbprptColumn(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(); + sql.append("SELECT ") + .append(String.join(", ", selectItems)) + .append(" FROM (") + .append(buildBaseMsstbprptViewSql()) + .append(") t WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = buildBaseMsstbprptFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0}); + 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 = mapBaseMsstbprptColumn(descriptor.getField()); + if (StrUtil.isNotBlank(column)) { + groupByColumns.add(column); + } + } + if (!groupByColumns.isEmpty()) { + sql.append(" GROUP BY ").append(String.join(", ", groupByColumns)).append(" "); + } + sql.append(buildBaseMsstbprptGroupOrderBySql(groups)); + + List> rows = microservicDynamicSQLMapper.pageAllList(null, sql.toString(), 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((long) rows.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private String buildBaseMsstbprptViewSql() { + return "SELECT " + + "eq.STCD AS stcd, " + + "eq.STNM AS stnm, " + + "eq.STTP AS sttpCode, " + + "CASE eq.STTP " + + " WHEN 'EQ_1' THEN '生态放流孔' " + + " WHEN 'EQ_2' THEN '生态放流闸' " + + " WHEN 'EQ_3' THEN '生态放流洞' " + + " WHEN 'EQ_4' THEN '生态放流管' " + + " WHEN 'EQ_5' THEN '基荷发电' " + + " WHEN 'EQ_6' THEN '生态机组' " + + " ELSE eq.STTP END AS sttpName, " + + "eq.RSTCD AS rstcd, " + + "eng.ENNM AS rstcdName, " + + "eq.BASE_ID AS baseId, " + + "hb.BASENAME AS baseName, " + + "eq.HBRVCD AS hbrvcd, " + + "hbrv.HBRVNM AS hbrvcdName, " + + "eq.STLC AS stlc, " + + "eq.LGTD AS lgtd, " + + "eq.LTTD AS lttd, " + + "eq.ELEV AS elev, " + + "eq.BLDSTT_CODE AS bldsttCode, " + + "CASE eq.BLDSTT_CODE WHEN 0 THEN '未建/规划' WHEN 1 THEN '在建' WHEN 2 THEN '已建' ELSE NULL END AS bldsttCodeName, " + + "eq.DTIN AS dtin, " + + "CASE NVL(eq.DTIN, 0) WHEN 1 THEN '是' WHEN 0 THEN '否' ELSE NULL END AS dtinName, " + + "eq.DTIN_TM AS dtinTm, " + + "eq.TM AS tm, " + + "eq.ORDER_INDEX AS orderIndex " + + "FROM SD_EQ_B_H eq " + + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = eq.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eq.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = eq.HBRVCD AND hbrv.BASEID = eq.BASE_ID " + + " AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1 " + + "WHERE NVL(eq.IS_DELETED, 0) = 0"; + } + + private String buildBaseMsstbprptDetailSelectSql(List selectFields) { + Map columns = baseMsstbprptFieldColumns(); + 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 Map baseMsstbprptFieldColumns() { + Map columns = new LinkedHashMap<>(); + columns.put("stcd", "t.stcd AS stcd"); + columns.put("stnm", "t.stnm AS stnm"); + columns.put("sttp", "t.sttpCode AS sttp"); + columns.put("sttpCode", "t.sttpCode AS sttpCode"); + columns.put("sttpName", "t.sttpName AS sttpName"); + columns.put("rstcd", "t.rstcd AS rstcd"); + columns.put("rstcdName", "t.rstcdName AS rstcdName"); + columns.put("baseId", "t.baseId AS baseId"); + columns.put("baseName", "t.baseName AS baseName"); + columns.put("hbrvcd", "t.hbrvcd AS hbrvcd"); + columns.put("hbrvcdName", "t.hbrvcdName AS hbrvcdName"); + columns.put("stlc", "t.stlc AS stlc"); + columns.put("lgtd", "t.lgtd AS lgtd"); + columns.put("lttd", "t.lttd AS lttd"); + columns.put("elev", "t.elev AS elev"); + columns.put("bldsttCode", "t.bldsttCode AS bldsttCode"); + columns.put("bldsttCodeName", "t.bldsttCodeName AS bldsttCodeName"); + columns.put("dtin", "t.dtin AS dtin"); + columns.put("dtinName", "t.dtinName AS dtinName"); + columns.put("dtinTm", "t.dtinTm AS dtinTm"); + columns.put("tm", "t.tm AS tm"); + columns.put("orderIndex", "t.orderIndex AS orderIndex"); + return columns; + } + private DataSourceResult queryMsstbprptDetailList(DataSourceRequest dataSourceRequest, DataSourceLoadOptionsBase loadOptions) { StringBuilder sql = new StringBuilder(); @@ -2808,6 +2997,74 @@ public class EngEqDataServiceImpl implements EngEqDataService { return orders.isEmpty() ? "" : " ORDER BY " + String.join(", ", orders); } + private String buildBaseMsstbprptFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + String column = mapBaseMsstbprptColumn(filter.getField()); + if (StrUtil.isBlank(column)) { + return ""; + } + return buildGenericCondition(column, filter, paramMap, indexHolder, isBaseMsstbprptDateField(filter.getField())); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildBaseMsstbprptFilterCondition(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 buildBaseMsstbprptDetailOrderBySql(List sortList) { + List orders = new ArrayList<>(); + if (CollUtil.isNotEmpty(sortList)) { + for (DataSourceRequest.SortDescriptor sort : sortList) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = mapBaseMsstbprptColumn(sort.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + orders.add(column + ("desc".equalsIgnoreCase(sort.getDir()) ? " DESC" : " ASC")); + } + } + if (orders.isEmpty()) { + orders.add("NVL(t.orderIndex, 999999) ASC"); + orders.add("t.stnm ASC"); + } + return " ORDER BY " + String.join(", ", orders); + } + + private String buildBaseMsstbprptGroupOrderBySql(List groups) { + List orders = new ArrayList<>(); + if (CollUtil.isNotEmpty(groups)) { + for (DataSourceRequest.GroupDescriptor descriptor : groups) { + if (descriptor == null || StrUtil.isBlank(descriptor.getField())) { + continue; + } + String column = mapBaseMsstbprptColumn(descriptor.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + orders.add(column + ("desc".equalsIgnoreCase(descriptor.getDir()) ? " DESC" : " ASC")); + } + } + return orders.isEmpty() ? "" : " ORDER BY " + String.join(", ", orders); + } + private String buildVmsstbprptFilterCondition(DataSourceRequest.FilterDescriptor filter, Map paramMap, int[] indexHolder) { @@ -4200,6 +4457,10 @@ public class EngEqDataServiceImpl implements EngEqDataService { return "tm".equalsIgnoreCase(field); } + private boolean isBaseMsstbprptDateField(String field) { + return "tm".equalsIgnoreCase(field) || "dtinTm".equalsIgnoreCase(field); + } + private boolean isEqDayDateField(String field) { return "dt".equalsIgnoreCase(field) || "tm".equalsIgnoreCase(field); } @@ -4783,6 +5044,36 @@ public class EngEqDataServiceImpl implements EngEqDataService { }; } + private String mapBaseMsstbprptColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "stcd" -> "t.stcd"; + case "stnm" -> "t.stnm"; + case "sttp", "sttpCode" -> "t.sttpCode"; + case "sttpName" -> "t.sttpName"; + case "rstcd" -> "t.rstcd"; + case "rstcdName" -> "t.rstcdName"; + case "baseId" -> "t.baseId"; + case "baseName" -> "t.baseName"; + case "hbrvcd" -> "t.hbrvcd"; + case "hbrvcdName" -> "t.hbrvcdName"; + case "stlc" -> "t.stlc"; + case "lgtd" -> "t.lgtd"; + case "lttd" -> "t.lttd"; + case "elev" -> "t.elev"; + case "bldsttCode" -> "t.bldsttCode"; + case "bldsttCodeName" -> "t.bldsttCodeName"; + case "dtin" -> "t.dtin"; + case "dtinName" -> "t.dtinName"; + case "dtinTm" -> "t.dtinTm"; + case "tm" -> "t.tm"; + case "orderIndex" -> "NVL(t.orderIndex, 999999)"; + default -> null; + }; + } + private String mapWbsbColumn(String field) { if (StrUtil.isBlank(field)) { return null; From c44c8d2229670d623a6719da1ea6ae015dc26424 Mon Sep 17 00:00:00 2001 From: tangwei Date: Thu, 18 Jun 2026 14:43:05 +0800 Subject: [PATCH 13/51] =?UTF-8?q?feat:=20=E7=94=9F=E6=80=81=E6=B5=81?= =?UTF-8?q?=E9=87=8F=E6=B3=84=E6=94=BE=E8=AE=BE=E6=96=BD=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eq/controller/EngEqDataController.java | 8 + .../eq/entity/vo/EngEqBaseVmsstbprptVo.java | 61 +++ .../qgc_eng/eq/service/EngEqDataService.java | 3 + .../eq/service/impl/EngEqDataServiceImpl.java | 370 +++++++++++++++++- 4 files changed, 434 insertions(+), 8 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqBaseVmsstbprptVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java index abff7d48..66190642 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java @@ -5,6 +5,7 @@ import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.config.ResponseResult; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqBaseMsstbprptVo; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqBaseVmsstbprptVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDrtpDataVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqIntervalVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqLimitQueryVo; @@ -81,6 +82,13 @@ public class EngEqDataController { return ResponseResult.successData(result); } + @PostMapping("/base/vmsstbprpt/GetKendoList") + @Operation(summary = "生态流量泄放设施统计查询") + public ResponseResult getBaseVmsstbprptList(@RequestBody DataSourceRequest dataSourceRequest) { + DataSourceResult result = engEqDataService.getBaseVmsstbprptList(dataSourceRequest); + return ResponseResult.successData(result); + } + @PostMapping("/interval/qgc/hour/GetKendoListCust") @Operation(summary = "生态流量达标率小时统计(二级页面)") public ResponseResult getQgcHourKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqBaseVmsstbprptVo.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqBaseVmsstbprptVo.java new file mode 100644 index 00000000..4b14d507 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqBaseVmsstbprptVo.java @@ -0,0 +1,61 @@ +package com.yfd.platform.qgc_eng.eq.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; + +@Data +@Schema(description = "生态流量泄放设施统计查询") +public class EngEqBaseVmsstbprptVo implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "设施类型编码") + private String sttpCode; + + @Schema(description = "设施类型名称") + private String sttpName; + + @Schema(description = "设施编码") + private String stcd; + + @Schema(description = "设施名称") + private String stnm; + + @Schema(description = "所属电站编码") + private String rstcd; + + @Schema(description = "所属电站名称") + private String rstcdName; + + @Schema(description = "基地编码") + private String baseId; + + @Schema(description = "基地名称") + private String baseName; + + @Schema(description = "基地流域编码") + private String hbrvcd; + + @Schema(description = "基地流域名称") + private String hbrvcdName; + + @Schema(description = "数据接入状态") + private Integer dtin; + + @Schema(description = "建设状态分类") + private Integer bldsttCode; + + @Schema(description = "基地排序") + private Integer baseStepSort; + + @Schema(description = "流域排序") + private Integer rvcdStepSort; + + @Schema(description = "所属电站排序") + private Integer rstcdStepSort; + + @Schema(description = "设施排序") + private Integer siteStepSort; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java index e1541b32..7f0a0bf8 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java @@ -3,6 +3,7 @@ package com.yfd.platform.qgc_eng.eq.service; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqBaseMsstbprptVo; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqBaseVmsstbprptVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDayDataVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDrtpDataVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDayIntervalVo; @@ -35,6 +36,8 @@ public interface EngEqDataService { DataSourceResult getBaseMsstbprptList(DataSourceRequest dataSourceRequest); + DataSourceResult getBaseVmsstbprptList(DataSourceRequest dataSourceRequest); + DataSourceResult getQgcHourKendoListCust(DataSourceRequest dataSourceRequest); DataSourceResult getQgcDayKendoListCust(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java index bb83777e..701cec27 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java @@ -13,6 +13,7 @@ import com.yfd.platform.common.MicroservicDynamicSQLMapper; import com.yfd.platform.common.enums.QecIntervalEnum; import com.yfd.platform.common.enums.ShowEnum; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqBaseMsstbprptVo; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqBaseVmsstbprptVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDataVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDayDataVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDrtpDataVo; @@ -112,6 +113,15 @@ public class EngEqDataServiceImpl implements EngEqDataService { return queryBaseMsstbprptGroupList(dataSourceRequest, loadOptions); } + @Override + public DataSourceResult getBaseVmsstbprptList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + if (CollUtil.isEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) { + return queryBaseVmsstbprptDetailList(dataSourceRequest, loadOptions); + } + return queryBaseVmsstbprptGroupList(dataSourceRequest, loadOptions); + } + private DataSourceResult queryBaseMsstbprptDetailList(DataSourceRequest dataSourceRequest, DataSourceLoadOptionsBase loadOptions) { StringBuilder sql = new StringBuilder(); @@ -202,6 +212,9 @@ public class EngEqDataServiceImpl implements EngEqDataService { } else { result.setData((List) (List) new GroupHelper().group(rows, Arrays.asList(groupInfos))); } + if (CollUtil.isNotEmpty((List) result.getData()) && ((List) result.getData()).get(0) instanceof Group) { + populateBaseMsstbprptGroupKeyNames((List) (List) result.getData()); + } result.setTotal((long) rows.size()); result.setAggregates(new HashMap<>()); return result; @@ -212,14 +225,7 @@ public class EngEqDataServiceImpl implements EngEqDataService { "eq.STCD AS stcd, " + "eq.STNM AS stnm, " + "eq.STTP AS sttpCode, " + - "CASE eq.STTP " + - " WHEN 'EQ_1' THEN '生态放流孔' " + - " WHEN 'EQ_2' THEN '生态放流闸' " + - " WHEN 'EQ_3' THEN '生态放流洞' " + - " WHEN 'EQ_4' THEN '生态放流管' " + - " WHEN 'EQ_5' THEN '基荷发电' " + - " WHEN 'EQ_6' THEN '生态机组' " + - " ELSE eq.STTP END AS sttpName, " + + "NVL(sttp.STTP_NAME, eq.STTP) AS sttpName, " + "eq.RSTCD AS rstcd, " + "eng.ENNM AS rstcdName, " + "eq.BASE_ID AS baseId, " + @@ -238,6 +244,8 @@ public class EngEqDataServiceImpl implements EngEqDataService { "eq.TM AS tm, " + "eq.ORDER_INDEX AS orderIndex " + "FROM SD_EQ_B_H eq " + + "LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = eq.STTP " + + " AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLE, 1) = 1 " + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = eq.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eq.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " + "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = eq.HBRVCD AND hbrv.BASEID = eq.BASE_ID " + @@ -291,6 +299,170 @@ public class EngEqDataServiceImpl implements EngEqDataService { return columns; } + private DataSourceResult queryBaseVmsstbprptDetailList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(buildBaseVmsstbprptDetailSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect())) + .append(" FROM (") + .append(buildBaseVmsstbprptViewSql()) + .append(") t WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = buildBaseVmsstbprptFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0}); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + sql.append(buildBaseVmsstbprptDetailOrderBySql(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, EngEqBaseVmsstbprptVo.class); + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private DataSourceResult queryBaseVmsstbprptGroupList(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 = mapBaseVmsstbprptColumn(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 = mapBaseVmsstbprptColumn(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(); + sql.append("SELECT ") + .append(String.join(", ", selectItems)) + .append(" FROM (") + .append(buildBaseVmsstbprptViewSql()) + .append(") t WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = buildBaseVmsstbprptFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0}); + 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 = mapBaseVmsstbprptColumn(descriptor.getField()); + if (StrUtil.isNotBlank(column)) { + groupByColumns.add(column); + } + } + if (!groupByColumns.isEmpty()) { + sql.append(" GROUP BY ").append(String.join(", ", groupByColumns)).append(" "); + } + sql.append(buildBaseVmsstbprptGroupOrderBySql(groups)); + + List> rows = microservicDynamicSQLMapper.pageAllList(null, sql.toString(), 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((long) rows.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private String buildBaseVmsstbprptViewSql() { + return "SELECT " + + "eq.STTP AS sttpCode, " + + "NVL(sttp.STTP_NAME, eq.STTP) AS sttpName, " + + "eq.STCD AS stcd, " + + "eq.STNM AS stnm, " + + "eq.RSTCD AS rstcd, " + + "eng.ENNM AS rstcdName, " + + "eq.BASE_ID AS baseId, " + + "hb.BASENAME AS baseName, " + + "eq.HBRVCD AS hbrvcd, " + + "hbrv.HBRVNM AS hbrvcdName, " + + "eq.DTIN AS dtin, " + + "eq.BLDSTT_CODE AS bldsttCode, " + + "NVL(hb.ORDER_INDEX, 999999) AS baseStepSort, " + + "NVL(along.ORDER_INDEX, 999999) AS rvcdStepSort, " + + "NVL(eng.ORDER_INDEX, 999999) AS rstcdStepSort, " + + "NVL(eq.ORDER_INDEX, 999999) AS siteStepSort " + + "FROM SD_EQ_B_H eq " + + "LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = eq.STTP " + + " AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLED, 1) = 1 " + + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = eq.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eq.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = eq.HBRVCD AND hbrv.BASEID = eq.BASE_ID " + + " AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1 " + + "LEFT JOIN MS_ALONG_B along ON along.RVCD = eq.HBRVCD AND along.CODE = 'common' AND NVL(along.IS_DELETED, 0) = 0 " + + "WHERE NVL(eq.IS_DELETED, 0) = 0"; + } + + private String buildBaseVmsstbprptDetailSelectSql(List selectFields) { + Map columns = baseVmsstbprptFieldColumns(); + 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 Map baseVmsstbprptFieldColumns() { + Map columns = new LinkedHashMap<>(); + columns.put("sttpCode", "t.sttpCode AS sttpCode"); + columns.put("sttpName", "t.sttpName AS sttpName"); + columns.put("stcd", "t.stcd AS stcd"); + columns.put("stnm", "t.stnm AS stnm"); + columns.put("rstcd", "t.rstcd AS rstcd"); + columns.put("rstcdName", "t.rstcdName AS rstcdName"); + columns.put("baseId", "t.baseId AS baseId"); + columns.put("baseName", "t.baseName AS baseName"); + columns.put("hbrvcd", "t.hbrvcd AS hbrvcd"); + columns.put("hbrvcdName", "t.hbrvcdName AS hbrvcdName"); + columns.put("dtin", "t.dtin AS dtin"); + columns.put("bldsttCode", "t.bldsttCode AS bldsttCode"); + columns.put("baseStepSort", "t.baseStepSort AS baseStepSort"); + columns.put("rvcdStepSort", "t.rvcdStepSort AS rvcdStepSort"); + columns.put("rstcdStepSort", "t.rstcdStepSort AS rstcdStepSort"); + columns.put("siteStepSort", "t.siteStepSort AS siteStepSort"); + return columns; + } + private DataSourceResult queryMsstbprptDetailList(DataSourceRequest dataSourceRequest, DataSourceLoadOptionsBase loadOptions) { StringBuilder sql = new StringBuilder(); @@ -1217,6 +1389,58 @@ public class EngEqDataServiceImpl implements EngEqDataService { populateHourDayGroupKeyNames(groups, baseNameCache, hbrvNameCache); } + private void populateBaseMsstbprptGroupKeyNames(List groups) { + if (CollUtil.isEmpty(groups)) { + return; + } + Map sttpNameCache = new HashMap<>(); + Map baseNameCache = new HashMap<>(); + Map hbrvNameCache = new HashMap<>(); + populateBaseMsstbprptGroupKeyNames(groups, sttpNameCache, baseNameCache, hbrvNameCache); + } + + private void populateBaseMsstbprptGroupKeyNames(List groups, + Map sttpNameCache, + Map baseNameCache, + Map hbrvNameCache) { + for (Group group : groups) { + if (group == null) { + continue; + } + if (StrUtil.isBlank(group.getKeyName())) { + group.setKeyName(resolveBaseMsstbprptGroupKeyName(group.getField(), group.getKey(), + sttpNameCache, baseNameCache, hbrvNameCache)); + } + if (CollUtil.isNotEmpty(group.getItems()) && group.getItems().get(0) instanceof Group) { + populateBaseMsstbprptGroupKeyNames((List) group.getItems(), sttpNameCache, baseNameCache, hbrvNameCache); + } + } + } + + private String resolveBaseMsstbprptGroupKeyName(Object field, + Object key, + Map sttpNameCache, + Map baseNameCache, + Map hbrvNameCache) { + if (field == null || key == null) { + return null; + } + String fieldName = String.valueOf(field); + String keyValue = String.valueOf(key); + if (StrUtil.isBlank(keyValue)) { + return null; + } + return switch (fieldName) { + case "sttpName", "stnm", "rstcdName", "baseName", "hbrvcdName", "bldsttCodeName", "dtinName" -> keyValue; + case "sttp", "sttpCode" -> StrUtil.blankToDefault(resolveSttpName(keyValue, sttpNameCache), keyValue); + case "baseId" -> StrUtil.blankToDefault(resolveBaseName(keyValue, baseNameCache), keyValue); + case "hbrvcd" -> StrUtil.blankToDefault(resolveHbrvName(keyValue, hbrvNameCache), keyValue); + case "dtin" -> resolveDtinName(keyValue); + case "bldsttCode" -> resolveBldsttName(keyValue); + default -> keyValue; + }; + } + private void populateHourDayGroupKeyNames(List groups, Map baseNameCache, Map hbrvNameCache) { @@ -1307,6 +1531,38 @@ public class EngEqDataServiceImpl implements EngEqDataService { return name == null ? null : String.valueOf(name); } + private String resolveSttpName(String sttpCode, Map cache) { + if (StrUtil.isBlank(sttpCode)) { + return null; + } + if (cache.containsKey(sttpCode)) { + return cache.get(sttpCode); + } + Map paramMap = new HashMap<>(); + paramMap.put("code", sttpCode); + List> rows = microservicDynamicSQLMapper.pageAllList(null, + "SELECT sttp.STTP_NAME AS name FROM SD_STTP_B sttp " + + "WHERE sttp.STTP_CODE = #{map.code} " + + "AND NVL(sttp.IS_DELETED, 0) = 0 " + + "AND NVL(sttp.ENABLE, 1) = 1 " + + "AND ROWNUM = 1", + paramMap); + String name = extractName(rows); + if (StrUtil.isBlank(name)) { + name = switch (sttpCode) { + case "EQ_1" -> "生态放流孔"; + case "EQ_2" -> "生态放流闸"; + case "EQ_3" -> "生态放流洞"; + case "EQ_4" -> "生态放流管"; + case "EQ_5" -> "基荷发电"; + case "EQ_6" -> "生态机组"; + default -> null; + }; + } + cache.put(sttpCode, name); + return name; + } + private String resolveDtinName(String keyValue) { return switch (keyValue) { case "1" -> "是"; @@ -2827,6 +3083,79 @@ public class EngEqDataServiceImpl implements EngEqDataService { return result; } + private String buildBaseVmsstbprptFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + String column = mapBaseVmsstbprptColumn(filter.getField()); + if (StrUtil.isBlank(column)) { + return ""; + } + return buildGenericCondition(column, filter, paramMap, indexHolder, false); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildBaseVmsstbprptFilterCondition(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 buildBaseVmsstbprptDetailOrderBySql(List sortList) { + if (CollUtil.isEmpty(sortList)) { + return " ORDER BY NVL(t.baseStepSort, 999999) ASC, NVL(t.rvcdStepSort, 999999) ASC, " + + "NVL(t.rstcdStepSort, 999999) ASC, NVL(t.siteStepSort, 999999) ASC, t.stcd ASC"; + } + List orders = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sortList) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = mapBaseVmsstbprptColumn(sort.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String dir = "desc".equalsIgnoreCase(sort.getDir()) || "des".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orders.add(column + " " + dir); + } + if (orders.isEmpty()) { + return " ORDER BY NVL(t.baseStepSort, 999999) ASC, NVL(t.rvcdStepSort, 999999) ASC, " + + "NVL(t.rstcdStepSort, 999999) ASC, NVL(t.siteStepSort, 999999) ASC, t.stcd ASC"; + } + return " ORDER BY " + String.join(", ", orders); + } + + private String buildBaseVmsstbprptGroupOrderBySql(List groups) { + if (CollUtil.isEmpty(groups)) { + return ""; + } + List orders = new ArrayList<>(); + for (DataSourceRequest.GroupDescriptor descriptor : groups) { + if (descriptor == null || StrUtil.isBlank(descriptor.getField())) { + continue; + } + String column = mapBaseVmsstbprptColumn(descriptor.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String dir = "desc".equalsIgnoreCase(descriptor.getDir()) || "des".equalsIgnoreCase(descriptor.getDir()) ? "DESC" : "ASC"; + orders.add(column + " " + dir); + } + return orders.isEmpty() ? "" : " ORDER BY " + String.join(", ", orders); + } + private DataSourceResult queryWbsbDetailList(DataSourceRequest dataSourceRequest, DataSourceLoadOptionsBase loadOptions) { StringBuilder sql = new StringBuilder(); @@ -5074,6 +5403,31 @@ public class EngEqDataServiceImpl implements EngEqDataService { }; } + private String mapBaseVmsstbprptColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "sttpCode" -> "t.sttpCode"; + case "sttpName" -> "t.sttpName"; + case "stcd" -> "t.stcd"; + case "stnm" -> "t.stnm"; + case "rstcd" -> "t.rstcd"; + case "rstcdName" -> "t.rstcdName"; + case "baseId" -> "t.baseId"; + case "baseName" -> "t.baseName"; + case "hbrvcd" -> "t.hbrvcd"; + case "hbrvcdName" -> "t.hbrvcdName"; + case "dtin" -> "t.dtin"; + case "bldsttCode" -> "t.bldsttCode"; + case "baseStepSort" -> "NVL(t.baseStepSort, 999999)"; + case "rvcdStepSort" -> "NVL(t.rvcdStepSort, 999999)"; + case "rstcdStepSort" -> "NVL(t.rstcdStepSort, 999999)"; + case "siteStepSort" -> "NVL(t.siteStepSort, 999999)"; + default -> null; + }; + } + private String mapWbsbColumn(String field) { if (StrUtil.isBlank(field)) { return null; From 675d6a19273de780be3a493d9e481f57b6b28e30 Mon Sep 17 00:00:00 2001 From: tangwei Date: Thu, 18 Jun 2026 15:45:35 +0800 Subject: [PATCH 14/51] =?UTF-8?q?feat:=20=E7=94=9F=E6=80=81=E6=B5=81?= =?UTF-8?q?=E9=87=8F=E6=B3=84=E6=94=BE=E8=AE=BE=E6=96=BD=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eq/entity/vo/EngEqBaseVmsstbprptVo.java | 36 +----- .../eq/service/impl/EngEqDataServiceImpl.java | 112 +++++++++++++++++- 2 files changed, 112 insertions(+), 36 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqBaseVmsstbprptVo.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqBaseVmsstbprptVo.java index 4b14d507..84f485a0 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqBaseVmsstbprptVo.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqBaseVmsstbprptVo.java @@ -2,51 +2,21 @@ package com.yfd.platform.qgc_eng.eq.entity.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; - -import java.io.Serializable; +import lombok.EqualsAndHashCode; @Data +@EqualsAndHashCode(callSuper = true) @Schema(description = "生态流量泄放设施统计查询") -public class EngEqBaseVmsstbprptVo implements Serializable { +public class EngEqBaseVmsstbprptVo extends EngEqMsstbprptVo { private static final long serialVersionUID = 1L; - @Schema(description = "设施类型编码") - private String sttpCode; - - @Schema(description = "设施类型名称") - private String sttpName; - - @Schema(description = "设施编码") - private String stcd; - - @Schema(description = "设施名称") - private String stnm; - @Schema(description = "所属电站编码") private String rstcd; @Schema(description = "所属电站名称") private String rstcdName; - @Schema(description = "基地编码") - private String baseId; - - @Schema(description = "基地名称") - private String baseName; - - @Schema(description = "基地流域编码") - private String hbrvcd; - - @Schema(description = "基地流域名称") - private String hbrvcdName; - - @Schema(description = "数据接入状态") - private Integer dtin; - - @Schema(description = "建设状态分类") - private Integer bldsttCode; - @Schema(description = "基地排序") private Integer baseStepSort; diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java index 701cec27..cc8cff1f 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java @@ -317,6 +317,7 @@ public class EngEqDataServiceImpl implements EngEqDataService { Page page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); List list = microservicDynamicSQLMapper.pageAllListWithResultType(page, sql.toString(), paramMap, EngEqBaseVmsstbprptVo.class); + fillBaseVmsstbprptDetailFields(list); DataSourceResult result = new DataSourceResult<>(); result.setData(list); result.setTotal(page != null ? page.getTotal() : list.size()); @@ -396,29 +397,68 @@ public class EngEqDataServiceImpl implements EngEqDataService { private String buildBaseVmsstbprptViewSql() { return "SELECT " + + "eq.STCD AS id, " + + "eq.RECORD_USER AS recordUser, " + + "eq.RECORD_TIME AS recordTime, " + + "eq.MODIFY_TIME AS modifyTime, " + "eq.STTP AS sttpCode, " + "NVL(sttp.STTP_NAME, eq.STTP) AS sttpName, " + + "sttp.ID AS sttp, " + + "sttp.FULL_PATH AS sttpFullPath, " + + "sttp.TREE_LEVEL AS sttpTreeLevel, " + "eq.STCD AS stcd, " + "eq.STNM AS stnm, " + + "eng.ENNM AS ennm, " + "eq.RSTCD AS rstcd, " + "eng.ENNM AS rstcdName, " + "eq.BASE_ID AS baseId, " + "hb.BASENAME AS baseName, " + "eq.HBRVCD AS hbrvcd, " + "hbrv.HBRVNM AS hbrvcdName, " + + "eng.RVCD AS rvcd, " + + "rv.RVNM AS rvcdName, " + + "eng.ADDVCD AS addvcd, " + + "addv.ADDVNM AS addvcdName, " + + "eng.COUNTRY AS country, " + + "eng.COUNTRY_NAME AS countryName, " + + "eng.HYCD AS hycd, " + + "eng.HYNM AS hynm, " + + "eng.TOP_HYCD AS topHycd, " + + "eng.TOP_HYNM AS topHynm, " + + "eq.BLPRD AS blprd, " + + "eq.LGTD AS lgtd, " + + "eq.LTTD AS lttd, " + + "eq.ELEV AS elev, " + + "eq.ELEV AS dtmel, " + + "eq.STLC AS stlc, " + + "eq.USFL AS usfl, " + "eq.DTIN AS dtin, " + - "eq.BLDSTT_CODE AS bldsttCode, " + + "CASE NVL(eq.DTIN, 0) WHEN 1 THEN '已接入' WHEN 0 THEN '未接入' ELSE NULL END AS dtinName, " + + "eq.DTIN_TM AS dtinTm, " + + "eq.INTRODUCE AS introduce, " + + "eq.LOGO AS logo, " + + "eq.INFFILE AS inffile, " + + "eng.PRSC AS prsc, " + + "eng.RUN_STATE AS runState, " + + "eng.BLDSTT AS bldstt, " + + "eng.BLDSTT_CODE AS bldsttCode, " + + "TO_CHAR(eng.BLDSTT_CODE) AS bldsttCcode, " + + "CASE NVL(eng.BLDSTT_CODE, -1) WHEN 0 THEN '未建/规划' WHEN 1 THEN '在建' WHEN 2 THEN '已建' ELSE NULL END AS bldsttCcodeName, " + "NVL(hb.ORDER_INDEX, 999999) AS baseStepSort, " + "NVL(along.ORDER_INDEX, 999999) AS rvcdStepSort, " + "NVL(eng.ORDER_INDEX, 999999) AS rstcdStepSort, " + - "NVL(eq.ORDER_INDEX, 999999) AS siteStepSort " + + "NVL(eq.ORDER_INDEX, 999999) AS siteStepSort, " + + "eq.ORDER_INDEX AS orderIndex, " + + "eq.TM AS tm " + "FROM SD_EQ_B_H eq " + "LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = eq.STTP " + - " AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLED, 1) = 1 " + + " AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLE, 1) = 1 " + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = eq.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eq.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " + "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = eq.HBRVCD AND hbrv.BASEID = eq.BASE_ID " + " AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1 " + + "LEFT JOIN SD_RVCD_DIC rv ON rv.RVCD = eng.RVCD " + + "LEFT JOIN SD_ADDVCD_DIC addv ON addv.ADDVCD = eng.ADDVCD " + "LEFT JOIN MS_ALONG_B along ON along.RVCD = eq.HBRVCD AND along.CODE = 'common' AND NVL(along.IS_DELETED, 0) = 0 " + "WHERE NVL(eq.IS_DELETED, 0) = 0"; } @@ -444,17 +484,54 @@ public class EngEqDataServiceImpl implements EngEqDataService { private Map baseVmsstbprptFieldColumns() { Map columns = new LinkedHashMap<>(); + columns.put("id", "t.id AS id"); + columns.put("recordUser", "t.recordUser AS recordUser"); + columns.put("recordTime", "t.recordTime AS recordTime"); + columns.put("modifyTime", "t.modifyTime AS modifyTime"); + columns.put("sttp", "t.sttp AS sttp"); columns.put("sttpCode", "t.sttpCode AS sttpCode"); columns.put("sttpName", "t.sttpName AS sttpName"); + columns.put("sttpFullPath", "t.sttpFullPath AS sttpFullPath"); + columns.put("sttpTreeLevel", "t.sttpTreeLevel AS sttpTreeLevel"); columns.put("stcd", "t.stcd AS stcd"); columns.put("stnm", "t.stnm AS stnm"); + columns.put("ennm", "t.ennm AS ennm"); columns.put("rstcd", "t.rstcd AS rstcd"); columns.put("rstcdName", "t.rstcdName AS rstcdName"); columns.put("baseId", "t.baseId AS baseId"); columns.put("baseName", "t.baseName AS baseName"); columns.put("hbrvcd", "t.hbrvcd AS hbrvcd"); columns.put("hbrvcdName", "t.hbrvcdName AS hbrvcdName"); + columns.put("rvcd", "t.rvcd AS rvcd"); + columns.put("rvcdName", "t.rvcdName AS rvcdName"); + columns.put("addvcd", "t.addvcd AS addvcd"); + columns.put("addvcdName", "t.addvcdName AS addvcdName"); + columns.put("country", "t.country AS country"); + columns.put("countryName", "t.countryName AS countryName"); + columns.put("hycd", "t.hycd AS hycd"); + columns.put("hynm", "t.hynm AS hynm"); + columns.put("topHycd", "t.topHycd AS topHycd"); + columns.put("topHynm", "t.topHynm AS topHynm"); + columns.put("blprd", "t.blprd AS blprd"); + columns.put("lgtd", "t.lgtd AS lgtd"); + columns.put("lttd", "t.lttd AS lttd"); + columns.put("elev", "t.elev AS elev"); + columns.put("dtmel", "t.dtmel AS dtmel"); + columns.put("stlc", "t.stlc AS stlc"); + columns.put("usfl", "t.usfl AS usfl"); columns.put("dtin", "t.dtin AS dtin"); + columns.put("dtinName", "t.dtinName AS dtinName"); + columns.put("dtinTm", "t.dtinTm AS dtinTm"); + columns.put("introduce", "t.introduce AS introduce"); + columns.put("logo", "t.logo AS logo"); + columns.put("inffile", "t.inffile AS inffile"); + columns.put("prsc", "t.prsc AS prsc"); + columns.put("runState", "t.runState AS runState"); + columns.put("bldstt", "t.bldstt AS bldstt"); + columns.put("bldsttCcode", "t.bldsttCcode AS bldsttCcode"); + columns.put("bldsttCcodeName", "t.bldsttCcodeName AS bldsttCcodeName"); + columns.put("orderIndex", "t.orderIndex AS orderIndex"); + columns.put("tm", "t.tm AS tm"); columns.put("bldsttCode", "t.bldsttCode AS bldsttCode"); columns.put("baseStepSort", "t.baseStepSort AS baseStepSort"); columns.put("rvcdStepSort", "t.rvcdStepSort AS rvcdStepSort"); @@ -463,6 +540,27 @@ public class EngEqDataServiceImpl implements EngEqDataService { return columns; } + private void fillBaseVmsstbprptDetailFields(List list) { + if (CollUtil.isEmpty(list)) { + return; + } + Map sttpNameCache = new HashMap<>(); + for (EngEqBaseVmsstbprptVo item : list) { + if (item == null) { + continue; + } + if (StrUtil.isBlank(item.getSttpName())) { + item.setSttpName(resolveSttpName(item.getSttpCode(), sttpNameCache)); + } + if (StrUtil.isBlank(item.getDtinName()) && item.getDtin() != null) { + item.setDtinName(resolveEqDtinName(String.valueOf(item.getDtin()))); + } + if (StrUtil.isBlank(item.getBldsttCcodeName()) && StrUtil.isNotBlank(item.getBldsttCcode())) { + item.setBldsttCcodeName(resolveBldsttName(item.getBldsttCcode())); + } + } + } + private DataSourceResult queryMsstbprptDetailList(DataSourceRequest dataSourceRequest, DataSourceLoadOptionsBase loadOptions) { StringBuilder sql = new StringBuilder(); @@ -1571,6 +1669,14 @@ public class EngEqDataServiceImpl implements EngEqDataService { }; } + private String resolveEqDtinName(String keyValue) { + return switch (keyValue) { + case "1" -> "已接入"; + case "0" -> "未接入"; + default -> keyValue; + }; + } + private String resolveDtinEnvName(String keyValue) { return switch (keyValue) { case "2" -> "已全部接入"; From 8fba065bc4722644b08ae1ddd1e88c1241ada643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=85=B4=E5=87=AF?= <2448379534@qq.com> Date: Mon, 22 Jun 2026 10:00:26 +0800 Subject: [PATCH 15/51] =?UTF-8?q?=E7=94=9F=E6=80=81=E6=B5=81=E9=87=8F?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=A0=A1=E5=87=86=E5=92=8C=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E6=8E=92=E5=BA=8F=E6=96=B9=E5=BC=8F=E7=9A=84?= =?UTF-8?q?=E6=9B=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/api/stll/index.ts | 8 +- frontend/src/components/BasicTable/index.vue | 82 ++++-- .../MapModal/components/EarlyWarningAlert.vue | 1 - .../SurveyQingKuang/DeviceTableModal.vue | 35 +-- .../ModalPage/index.vue | 51 +--- .../qixidiheduanjianceqingkuangEJ/index.vue | 82 ++---- .../xieFangFangShi/TwoLayer/STLLXFFS.vue | 87 ++---- .../xieFangFangShi/index.vue | 45 ++- .../TwoLayer/FenBuQingKuangTwoLayer.vue | 72 ++--- .../TwoLayer/ModalYkzhbzdjcgz.vue | 47 +-- .../ShengTaiLiuLiangDaBQKTwoLayer.vue | 54 +--- .../TwoLayer/STLLXFFS.vue | 90 +++--- .../modules/shengtaidabiaoTwoMod/index.vue | 269 ++++++++++++------ 13 files changed, 419 insertions(+), 504 deletions(-) diff --git a/frontend/src/api/stll/index.ts b/frontend/src/api/stll/index.ts index 4eaf0cd0..58db464a 100644 --- a/frontend/src/api/stll/index.ts +++ b/frontend/src/api/stll/index.ts @@ -34,7 +34,7 @@ export function evnmAutoMonitorGetKendoListCust(queryParams: any) { //获取电站 export function vmsstbprptGetKendoList(queryParams: any) { return request({ - url: '/eq/vmsstbprpt/GetKendoList', + url: '/eq/base/vmsstbprpt/GetKendoList', method: 'post', data: queryParams }); @@ -58,7 +58,7 @@ export function intervalGetKendoListCust(queryParams: any) { // 获取生态流量达标率按性能 export function eqGetKendoListCust(queryParams: any) { return request({ - url: '/api/wmp-eng-server/eng/to/eq/GetKendoListCust', + url: '/eq/to/eq/GetKendoListCust', method: 'post', data: queryParams }); @@ -82,7 +82,7 @@ export function wbsbGetKendoList(queryParams: any) { //生态流量泄放方式 export function msstbprptGetKendoList(queryParams: any) { return request({ - url: '/eq/msstbprpt/GetKendoList', + url: '/eq/base/msstbprpt/GetKendoList', method: 'post', data: queryParams }); @@ -90,7 +90,7 @@ export function msstbprptGetKendoList(queryParams: any) { //根据流域获取电站 export function qgcgetEngLimit(queryParams: any) { return request({ - url: '/api/wmp-eng-server/eng/engalong/statistics/qgc/getEngLimit', + url: '/eq/engalong/statistics/qgc/getEngLimit', method: 'post', data: queryParams }); diff --git a/frontend/src/components/BasicTable/index.vue b/frontend/src/components/BasicTable/index.vue index f124d5be..0671418a 100644 --- a/frontend/src/components/BasicTable/index.vue +++ b/frontend/src/components/BasicTable/index.vue @@ -101,6 +101,12 @@ const lastFilter = ref | undefined>(undefined); const tableContainerRef = ref(null); const tableScrollY = ref(0); // ✅ 新增:存储容器高度 +// --- 内部排序状态 --- +const internalSort = ref<{ + field: string; + order: 'ascend' | 'descend' | null; +}>({ field: '', order: null }); + // --- Computed Scroll Config --- const scrollConfig = computed(() => { const config: any = { @@ -177,10 +183,23 @@ const getList = async (filter?: Record) => { if (filter !== undefined) { lastFilter.value = filter; } - console.log(props.searchParams); try { + // 合并排序参数:优先使用用户手动排序,否则使用 searchParams 中的默认排序 + let sort = undefined; + if (internalSort.value.field && internalSort.value.order) { + sort = [ + { + field: internalSort.value.field, + dir: internalSort.value.order === 'ascend' ? 'asc' : 'desc' + } + ]; + } else if (props.searchParams?.sort) { + sort = props.searchParams.sort; + } + const params = { ...props.searchParams, + ...(sort !== undefined ? { sort } : {}), skip: page.value, take: size.value, filter: lastFilter.value @@ -219,14 +238,17 @@ const getList = async (filter?: Record) => { const handleTableChange = (pag: any, filters: any, sorter: any) => { page.value = pag.current; size.value = pag.pageSize; - if (props.enableSort) { - if (sorter && sorter.field) { - emit('sort-change', { field: sorter.field, order: sorter.order }); - } else { - emit('sort-change', { field: '', order: null }); - } - } else { + if (sorter && sorter.field) { + internalSort.value = { field: sorter.field, order: sorter.order }; + page.value = 1; // 排序时重置到第一页 getList(); + emit('sort-change', { field: sorter.field, order: sorter.order }); + } else { + // 清除排序 + internalSort.value = { field: '', order: null }; + page.value = 1; + getList(); + emit('sort-change', { field: '', order: null }); } }; const handleRowClick = (record: any) => { @@ -264,6 +286,9 @@ defineExpose({ refresh, tableData, clearSelection, + clearSort: () => { + internalSort.value = { field: '', order: null }; + }, getSelected: () => ({ keys: selectedRowKeys.value, rows: selectedRows.value @@ -351,19 +376,28 @@ const createMergeCellHandler = (dataIndex: string) => { }; }; -// --- 列配置增强(超出隐藏 + Tooltip + 插槽兼容 + 行合并)--- +// --- 列配置增强(超出隐藏 + Tooltip + 插槽兼容 + 行合并 + 排序)--- const enhancedColumns = computed(() => { return props.columns.map(col => { + const enhancedCol: any = { ...col }; + + // 处理 sort 或 sorter: true,统一转为 sorter 并绑定 sortOrder + const isSortable = enhancedCol.sort === true || enhancedCol.sorter === true; + if (isSortable) { + enhancedCol.sorter = true; + enhancedCol.sortOrder = + internalSort.value.field === enhancedCol.dataIndex + ? internalSort.value.order + : false; + } + // 处理 merge 配置 - if (col.merge && col.dataIndex) { - const baseCol = { - ...col, - customCell: createMergeCellHandler(col.dataIndex) - }; + if (enhancedCol.merge && enhancedCol.dataIndex) { + enhancedCol.customCell = createMergeCellHandler(enhancedCol.dataIndex); // 如果有 slots.customRender,移除 slots - if (baseCol.slots?.customRender) { - const { slots, ...restCol } = baseCol; + if (enhancedCol.slots?.customRender) { + const { slots, ...restCol } = enhancedCol; return { ...restCol, _slotName: slots.customRender, @@ -371,12 +405,12 @@ const enhancedColumns = computed(() => { }; } - return baseCol; + return enhancedCol; } // 如果有 slots.customRender,移除 slots(由 bodyCell 处理),保留 dataIndex 用于匹配 - if (col.slots?.customRender) { - const { slots, ...restCol } = col; + if (enhancedCol.slots?.customRender) { + const { slots, ...restCol } = enhancedCol; return { ...restCol, // 保留 slotName 供 bodyCell 模板匹配使用 @@ -386,18 +420,18 @@ const enhancedColumns = computed(() => { } // 如果已有 customRender 函数,直接返回 - if (col.customRender) { + if (enhancedCol.customRender) { return { - ...col, - ...(props.enableEllipsis && !col.ellipsis ? { ellipsis: true } : {}) + ...enhancedCol, + ...(props.enableEllipsis && !enhancedCol.ellipsis ? { ellipsis: true } : {}) }; } // 普通列,添加 ellipsis - if (!props.enableEllipsis) return col; + if (!props.enableEllipsis) return enhancedCol; return { - ...col, + ...enhancedCol, ellipsis: true }; }); diff --git a/frontend/src/components/MapModal/components/EarlyWarningAlert.vue b/frontend/src/components/MapModal/components/EarlyWarningAlert.vue index 0afb7285..7d7488da 100644 --- a/frontend/src/components/MapModal/components/EarlyWarningAlert.vue +++ b/frontend/src/components/MapModal/components/EarlyWarningAlert.vue @@ -8,7 +8,6 @@ :columns="currentColumns" :list-url="fetchTableData" :search-params="searchParams" - :enable-sort="true" /> diff --git a/frontend/src/modules/fishSurvey/SurveyQingKuang/DeviceTableModal.vue b/frontend/src/modules/fishSurvey/SurveyQingKuang/DeviceTableModal.vue index 68e8558b..b9fb5571 100644 --- a/frontend/src/modules/fishSurvey/SurveyQingKuang/DeviceTableModal.vue +++ b/frontend/src/modules/fishSurvey/SurveyQingKuang/DeviceTableModal.vue @@ -55,8 +55,6 @@ :list-url="sdFprdRGetKendoListCust" :search-params="tableSearchParams" :transform-data="customTransform" - :enable-sort="true" - @sort-change="handleSortChange" >