From 7d230273e89ba1989d509731b1296f37949c135c Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 1 Jun 2026 08:49:14 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A7=86=E9=A2=91=E7=9B=91=E6=8E=A7?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=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 --- .../yfd/platform/config/SecurityConfig.java | 1 + .../yfd/platform/config/SwaggerConfig.java | 8 + .../vd/controller/VdMonitorController.java | 29 +++ .../qgc_env/vd/entity/vo/VdVmsstbprptVo.java | 25 ++ .../qgc_env/vd/service/VdMonitorService.java | 10 + .../vd/service/impl/VdMonitorServiceImpl.java | 233 ++++++++++++++++++ 6 files changed, 306 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/vd/controller/VdMonitorController.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/vd/entity/vo/VdVmsstbprptVo.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/vd/service/VdMonitorService.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/vd/service/impl/VdMonitorServiceImpl.java diff --git a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java index d04d95c5..b4323148 100644 --- a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java @@ -63,6 +63,7 @@ public class SecurityConfig { .requestMatchers("/wt/**").permitAll() .requestMatchers("/zq/**").permitAll() .requestMatchers("/wq/**").permitAll() + .requestMatchers("/vd/**").permitAll() .requestMatchers("/fp/**").permitAll() .requestMatchers("/fh/**").permitAll() .requestMatchers("/data/**").permitAll() diff --git a/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java b/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java index 18d33404..9178996a 100644 --- a/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java @@ -84,6 +84,14 @@ public class SwaggerConfig { .build(); } + @Bean + public GroupedOpenApi groupEnvVDApi() { + return GroupedOpenApi.builder() + .group("3.3.1 全过程-生态环保数据服务-过鱼设施-过鱼监测") + .packagesToScan("com.yfd.platform.qgc_env.vd.controller") + .build(); + } + @Bean public GroupedOpenApi groupEnvFHApi() { return GroupedOpenApi.builder() diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vd/controller/VdMonitorController.java b/backend/src/main/java/com/yfd/platform/qgc_env/vd/controller/VdMonitorController.java new file mode 100644 index 00000000..a2d2193f --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vd/controller/VdMonitorController.java @@ -0,0 +1,29 @@ +package com.yfd.platform.qgc_env.vd.controller; + +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.qgc_env.vd.service.VdMonitorService; +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("/vd") +@Tag(name = "视频监控模块") +@Validated +public class VdMonitorController { + + @Resource + private VdMonitorService vdMonitorService; + + @PostMapping("/vmsstbprpt/GetKendoList") + @Operation(summary = "视频监控设备统计查询") + public ResponseResult getVmsstbprptList(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(vdMonitorService.getVmsstbprptList(dataSourceRequest)); + } +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vd/entity/vo/VdVmsstbprptVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/vd/entity/vo/VdVmsstbprptVo.java new file mode 100644 index 00000000..70783d4a --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vd/entity/vo/VdVmsstbprptVo.java @@ -0,0 +1,25 @@ +package com.yfd.platform.qgc_env.vd.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; + +@Data +@Schema(description = "视频监控设备分组统计") +public class VdVmsstbprptVo implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "站类编码") + private String sttpCode; + + @Schema(description = "站类值") + private String sttpCodeValue; + + @Schema(description = "站类扩展") + private Object sttpCodeExt; + + @Schema(description = "站类数量") + private Integer countSttpCode; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vd/service/VdMonitorService.java b/backend/src/main/java/com/yfd/platform/qgc_env/vd/service/VdMonitorService.java new file mode 100644 index 00000000..18d05d5a --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vd/service/VdMonitorService.java @@ -0,0 +1,10 @@ +package com.yfd.platform.qgc_env.vd.service; + +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.common.DataSourceResult; +import com.yfd.platform.qgc_env.vd.entity.vo.VdVmsstbprptVo; + +public interface VdMonitorService { + + DataSourceResult getVmsstbprptList(DataSourceRequest dataSourceRequest); +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vd/service/impl/VdMonitorServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/vd/service/impl/VdMonitorServiceImpl.java new file mode 100644 index 00000000..eafc9041 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vd/service/impl/VdMonitorServiceImpl.java @@ -0,0 +1,233 @@ +package com.yfd.platform.qgc_env.vd.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.yfd.platform.common.DataSourceLoadOptionsBase; +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.common.DataSourceResult; +import com.yfd.platform.common.GroupHelper; +import com.yfd.platform.common.GroupingInfo; +import com.yfd.platform.common.MicroservicDynamicSQLMapper; +import com.yfd.platform.qgc_env.vd.entity.vo.VdVmsstbprptVo; +import com.yfd.platform.qgc_env.vd.service.VdMonitorService; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class VdMonitorServiceImpl implements VdMonitorService { + + @Resource + private MicroservicDynamicSQLMapper microservicDynamicSQLMapper; + + @Override + public DataSourceResult getVmsstbprptList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + GroupingInfo[] groups = loadOptions == null ? null : loadOptions.getGroup(); + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT t.STTP_CODE AS sttpCode, COUNT(1) AS COUNT_STTPCODE ") + .append("FROM (") + .append(buildUnionBaseSql()) + .append(") t ") + .append("WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = buildFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0}); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + + sql.append(" GROUP BY t.STTP_CODE "); + sql.append(buildOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getGroup())); + + List> rows = microservicDynamicSQLMapper.pageAllList(null, sql.toString(), paramMap); + DataSourceResult result = new DataSourceResult<>(); + if (groups != null && groups.length > 0) { + if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) { + result.setData((List) (List) new GroupHelper().faltGroup(rows, Arrays.asList(groups))); + result.setTotal((long) rows.size()); + } else { + result.setData((List) (List) new GroupHelper().group(rows, Arrays.asList(groups))); + result.setTotal((long) rows.size()); + } + } else { + List data = new ArrayList<>(); + for (Map row : rows) { + VdVmsstbprptVo vo = new VdVmsstbprptVo(); + Object sttpCode = row.get("STTPCODE"); + Object count = row.get("COUNT_STTPCODE"); + vo.setSttpCode(sttpCode == null ? null : sttpCode.toString()); + vo.setSttpCodeValue(sttpCode == null ? null : sttpCode.toString()); + vo.setSttpCodeExt(null); + vo.setCountSttpCode(count == null ? 0 : Integer.parseInt(count.toString())); + data.add(vo); + } + result.setData(data); + result.setTotal((long) data.size()); + } + result.setAggregates(new HashMap<>()); + return result; + } + + private String buildUnionBaseSql() { + return "SELECT vd.STCD, vd.STTP AS STTP_CODE, sttp.STTP_NAME, sttp.FULL_PATH " + + "FROM SD_VDINFO_B vd " + + "LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = vd.STTP " + + " AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLE, 1) = 1 " + + "WHERE NVL(vd.USFL, 1) = 1 AND vd.STTP = 'VD_FP' " + + "UNION ALL " + + "SELECT sonar.STCD, sonar.STTP AS STTP_CODE, sttp.STTP_NAME, sttp.FULL_PATH " + + "FROM SD_SONAR_B_H sonar " + + "LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = sonar.STTP " + + " AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLE, 1) = 1 " + + "WHERE NVL(sonar.IS_DELETED, 0) = 0 AND sonar.STTP IN ('VD_WVD', 'VD_SN') "; + } + + private String buildFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildFilterCondition(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 buildLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String column = mapColumn(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 = normalizeValues(value); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + for (Object item : values) { + String paramKey = "vdParam" + indexHolder[0]++; + paramMap.put(paramKey, item); + placeholders.add("#{map." + paramKey + "}"); + } + return column + " IN (" + String.join(", ", placeholders) + ")"; + } + if (value == null) { + return ""; + } + String paramKey = "vdParam" + indexHolder[0]++; + return switch (operator) { + case "eq" -> { + paramMap.put(paramKey, value); + yield column + " = #{map." + paramKey + "}"; + } + case "neq" -> { + paramMap.put(paramKey, value); + yield column + " <> #{map." + paramKey + "}"; + } + case "contains" -> { + paramMap.put(paramKey, "%" + value + "%"); + yield column + " LIKE #{map." + paramKey + "}"; + } + case "startswith" -> { + paramMap.put(paramKey, value + "%"); + yield column + " LIKE #{map." + paramKey + "}"; + } + case "endswith" -> { + paramMap.put(paramKey, "%" + value); + yield column + " LIKE #{map." + paramKey + "}"; + } + default -> ""; + }; + } + + private List normalizeValues(Object value) { + List values = new ArrayList<>(); + if (value instanceof List list) { + for (Object item : list) { + if (item != null) { + values.add(item); + } + } + return values; + } + if (value instanceof Object[] array) { + for (Object item : array) { + if (item != null) { + values.add(item); + } + } + return values; + } + if (value != null) { + values.add(value); + } + return values; + } + + private String mapColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "sttpCode" -> "t.STTP_CODE"; + case "sttpName" -> "t.STTP_NAME"; + case "sttpFullPath" -> "t.FULL_PATH"; + case "stcd" -> "t.STCD"; + default -> null; + }; + } + + private String buildOrderBySql(List groups) { + if (CollUtil.isEmpty(groups)) { + return " ORDER BY t.STTP_CODE ASC"; + } + List orderItems = new ArrayList<>(); + for (DataSourceRequest.GroupDescriptor group : groups) { + if (group == null || StrUtil.isBlank(group.getField())) { + continue; + } + String column = mapColumn(group.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String direction = "desc".equalsIgnoreCase(group.getDir()) ? "DESC" : "ASC"; + orderItems.add(column + " " + direction); + } + if (orderItems.isEmpty()) { + return " ORDER BY t.STTP_CODE ASC"; + } + return " ORDER BY " + String.join(", ", orderItems); + } +}