diff --git a/src/main/java/com/ycwl/basic/integration/device/client/DeviceV2Client.java b/src/main/java/com/ycwl/basic/integration/device/client/DeviceV2Client.java index 106c982..0e13675 100644 --- a/src/main/java/com/ycwl/basic/integration/device/client/DeviceV2Client.java +++ b/src/main/java/com/ycwl/basic/integration/device/client/DeviceV2Client.java @@ -76,4 +76,11 @@ public interface DeviceV2Client { @RequestParam(value = "type", required = false) String type, @RequestParam(value = "isActive", required = false) Integer isActive, @RequestParam(value = "scenicId", required = false) Long scenicId); + + /** + * 根据配置条件筛选设备 + */ + @PostMapping("/filter-by-configs") + CommonResponse filterDevicesByConfigs( + @RequestBody FilterDevicesByConfigsRequest request); } \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/integration/device/dto/device/ConfigFilter.java b/src/main/java/com/ycwl/basic/integration/device/dto/device/ConfigFilter.java new file mode 100644 index 0000000..bd20e09 --- /dev/null +++ b/src/main/java/com/ycwl/basic/integration/device/dto/device/ConfigFilter.java @@ -0,0 +1,29 @@ +package com.ycwl.basic.integration.device.dto.device; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 配置筛选条件 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ConfigFilter { + /** + * 配置键名 + */ + private String configKey; + + /** + * 配置值(某些操作符不需要,如 is_null、is_not_null) + */ + private Object configValue; + + /** + * 比较操作符 + * 支持: eq, ne, like, gt, lt, gte, lte, in, not_in, is_null, is_not_null + */ + private String operator; +} \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/integration/device/dto/device/FilterDevicesByConfigsRequest.java b/src/main/java/com/ycwl/basic/integration/device/dto/device/FilterDevicesByConfigsRequest.java new file mode 100644 index 0000000..2816b11 --- /dev/null +++ b/src/main/java/com/ycwl/basic/integration/device/dto/device/FilterDevicesByConfigsRequest.java @@ -0,0 +1,41 @@ +package com.ycwl.basic.integration.device.dto.device; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Map; + +/** + * 根据配置筛选设备请求 + */ +@Data +@NoArgsConstructor +public class FilterDevicesByConfigsRequest { + /** + * 页码,默认1 + */ + private Integer page = 1; + + /** + * 每页数量,默认10 + */ + private Integer pageSize = 10; + + /** + * 配置筛选条件列表,至少包含一个条件 + */ + private List configFilters; + + /** + * 多个条件间的逻辑关系,默认"AND" + * 支持: "AND", "OR" + */ + private String filterLogic = "AND"; + + /** + * 设备基本信息筛选条件 + * 可包含: name, no, type, isActive, scenicId + */ + private Map deviceFilters; +} \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/integration/device/dto/device/FilterDevicesByConfigsResponse.java b/src/main/java/com/ycwl/basic/integration/device/dto/device/FilterDevicesByConfigsResponse.java new file mode 100644 index 0000000..cd957a4 --- /dev/null +++ b/src/main/java/com/ycwl/basic/integration/device/dto/device/FilterDevicesByConfigsResponse.java @@ -0,0 +1,31 @@ +package com.ycwl.basic.integration.device.dto.device; + +import lombok.Data; + +import java.util.List; + +/** + * 根据配置筛选设备响应数据 + */ +@Data +public class FilterDevicesByConfigsResponse { + /** + * 设备列表 + */ + private List list; + + /** + * 总数 + */ + private String total; + + /** + * 页码 + */ + private Integer page; + + /** + * 每页数量 + */ + private Integer pageSize; +} \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/integration/device/example/DeviceFilterExample.java b/src/main/java/com/ycwl/basic/integration/device/example/DeviceFilterExample.java new file mode 100644 index 0000000..d7c91a2 --- /dev/null +++ b/src/main/java/com/ycwl/basic/integration/device/example/DeviceFilterExample.java @@ -0,0 +1,190 @@ +package com.ycwl.basic.integration.device.example; + +import com.ycwl.basic.integration.device.dto.device.*; +import com.ycwl.basic.integration.device.service.DeviceIntegrationService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 设备配置筛选功能使用示例 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class DeviceFilterExample { + + private final DeviceIntegrationService deviceIntegrationService; + + /** + * 示例1: 查找高质量户外IPC设备 + * 条件: 分辨率1920x1080,帧率>=30,位置包含"outdoor" + */ + public void findHighQualityOutdoorDevices() { + log.info("=== 查找高质量户外IPC设备 ==="); + + List configFilters = Arrays.asList( + new ConfigFilter("resolution", "1920x1080", "eq"), + new ConfigFilter("framerate", 30, "gte"), + new ConfigFilter("location", "outdoor", "like") + ); + + Map deviceFilters = new HashMap<>(); + deviceFilters.put("type", "IPC"); + deviceFilters.put("isActive", 1); + + FilterDevicesByConfigsRequest request = new FilterDevicesByConfigsRequest(); + request.setPage(1); + request.setPageSize(20); + request.setConfigFilters(configFilters); + request.setFilterLogic("AND"); + request.setDeviceFilters(deviceFilters); + + try { + FilterDevicesByConfigsResponse response = deviceIntegrationService.filterDevicesByConfigs(request); + log.info("找到 {} 个高质量户外IPC设备", response.getTotal()); + + response.getList().forEach(device -> { + log.info("设备: {} ({}), 配置: {}", device.getName(), device.getNo(), device.getConfig()); + }); + } catch (Exception e) { + log.error("查找高质量户外IPC设备失败", e); + } + } + + /** + * 示例2: 查找缺少关键配置的设备 + * 条件: 缺少备份服务器或夜视功能配置 + */ + public void findDevicesWithMissingConfigs() { + log.info("=== 查找缺少关键配置的设备 ==="); + + List configFilters = Arrays.asList( + new ConfigFilter("backup_server", null, "is_null"), + new ConfigFilter("night_vision", null, "is_null") + ); + + FilterDevicesByConfigsRequest request = new FilterDevicesByConfigsRequest(); + request.setConfigFilters(configFilters); + request.setFilterLogic("OR"); // 缺少任一配置即返回 + request.setPageSize(50); + + try { + FilterDevicesByConfigsResponse response = deviceIntegrationService.filterDevicesByConfigs(request); + log.info("找到 {} 个缺少关键配置的设备", response.getTotal()); + + response.getList().forEach(device -> { + Map config = device.getConfig(); + boolean missingBackup = !config.containsKey("backup_server") || config.get("backup_server") == null; + boolean missingNightVision = !config.containsKey("night_vision") || config.get("night_vision") == null; + + log.info("设备: {} ({}), 缺少配置: {}{}", + device.getName(), device.getNo(), + missingBackup ? "备份服务器 " : "", + missingNightVision ? "夜视功能 " : ""); + }); + } catch (Exception e) { + log.error("查找缺少关键配置的设备失败", e); + } + } + + /** + * 示例3: 根据多个位置查找设备 + * 条件: 位置在指定列表中 + */ + public void findDevicesByMultipleLocations() { + log.info("=== 根据多个位置查找设备 ==="); + + List locations = Arrays.asList("outdoor", "indoor", "parking"); + List configFilters = Arrays.asList( + new ConfigFilter("location", locations, "in") + ); + + FilterDevicesByConfigsRequest request = new FilterDevicesByConfigsRequest(); + request.setConfigFilters(configFilters); + request.setPageSize(100); + + try { + FilterDevicesByConfigsResponse response = deviceIntegrationService.filterDevicesByConfigs(request); + log.info("找到 {} 个设备在指定位置", response.getTotal()); + + response.getList().forEach(device -> { + Object location = device.getConfig().get("location"); + log.info("设备: {} ({}), 位置: {}", device.getName(), device.getNo(), location); + }); + } catch (Exception e) { + log.error("根据多个位置查找设备失败", e); + } + } + + /** + * 示例4: 使用便捷方法查找设备 + */ + public void useConvenienceMethods() { + log.info("=== 使用便捷方法查找设备 ==="); + + try { + // 查找缺少配置的设备 + FilterDevicesByConfigsResponse response4 = deviceIntegrationService + .findDevicesWithMissingConfig("firmware_version", 1, 10); + log.info("缺少固件版本配置的设备数: {}", response4.getTotal()); + + } catch (Exception e) { + log.error("使用便捷方法查找设备失败", e); + } + } + + /** + * 示例5: 性能监控查询 + * 条件: CPU使用率>80% 或 内存使用率>85% + */ + public void findHighLoadDevices() { + log.info("=== 查找高负载设备 ==="); + + List configFilters = Arrays.asList( + new ConfigFilter("cpu_usage", 80, "gt"), + new ConfigFilter("memory_usage", 85, "gt") + ); + + FilterDevicesByConfigsRequest request = new FilterDevicesByConfigsRequest(); + request.setConfigFilters(configFilters); + request.setFilterLogic("OR"); + request.setPageSize(50); + + try { + FilterDevicesByConfigsResponse response = deviceIntegrationService.filterDevicesByConfigs(request); + log.info("找到 {} 个高负载设备", response.getTotal()); + + response.getList().forEach(device -> { + Map config = device.getConfig(); + Object cpuUsage = config.get("cpu_usage"); + Object memoryUsage = config.get("memory_usage"); + + log.info("高负载设备: {} ({}), CPU: {}%, 内存: {}%", + device.getName(), device.getNo(), cpuUsage, memoryUsage); + }); + } catch (Exception e) { + log.error("查找高负载设备失败", e); + } + } + + /** + * 运行所有示例 + */ + public void runAllExamples() { + log.info("开始运行设备配置筛选示例..."); + + findHighQualityOutdoorDevices(); + findDevicesWithMissingConfigs(); + findDevicesByMultipleLocations(); + useConvenienceMethods(); + findHighLoadDevices(); + + log.info("所有示例运行完成"); + } +} \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/integration/device/service/DeviceIntegrationService.java b/src/main/java/com/ycwl/basic/integration/device/service/DeviceIntegrationService.java index 3dfe39e..8e49e71 100644 --- a/src/main/java/com/ycwl/basic/integration/device/service/DeviceIntegrationService.java +++ b/src/main/java/com/ycwl/basic/integration/device/service/DeviceIntegrationService.java @@ -9,6 +9,8 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import java.util.List; + @Slf4j @Service @RequiredArgsConstructor @@ -205,6 +207,27 @@ public class DeviceIntegrationService { return listDevices(page, pageSize, null, null, null, 1, scenicId); } + /** + * 根据配置条件筛选设备 + */ + public FilterDevicesByConfigsResponse filterDevicesByConfigs(FilterDevicesByConfigsRequest request) { + log.info("根据配置条件筛选设备, page: {}, pageSize: {}, filterLogic: {}, configFilters: {}", + request.getPage(), request.getPageSize(), request.getFilterLogic(), request.getConfigFilters()); + CommonResponse response = deviceV2Client.filterDevicesByConfigs(request); + return handleResponse(response, "根据配置条件筛选设备失败"); + } + + /** + * 查找缺少指定配置的设备 + */ + public FilterDevicesByConfigsResponse findDevicesWithMissingConfig(String configKey, Integer page, Integer pageSize) { + FilterDevicesByConfigsRequest request = new FilterDevicesByConfigsRequest(); + request.setPage(page != null ? page : 1); + request.setPageSize(pageSize != null ? pageSize : 20); + request.setConfigFilters(List.of(new ConfigFilter(configKey, null, "is_null"))); + return filterDevicesByConfigs(request); + } + private T handleResponse(CommonResponse response, String errorMessage) { if (response == null || !response.isSuccess()) { String msg = response != null && response.getMessage() != null