Browse Source

fix: 优化用户聚合单位

jackzhou 7 months ago
parent
commit
c8d30a3e45

+ 4 - 3
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/JfcloudSensorDataService.java

@@ -9,6 +9,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.Assert;
 import vip.xiaonuo.coldchain.core.bean.influxdb.SensorData;
 import vip.xiaonuo.coldchain.core.util.DateFormatter;
+import vip.xiaonuo.coldchain.modular.app.param.AggregationWindow;
 
 import java.time.Instant;
 import java.time.LocalDateTime;
@@ -98,7 +99,7 @@ public class JfcloudSensorDataService extends JfcloudFluxDataService<SensorData>
 //                .collect(Collectors.toList());
 //    }
 
-    public List<SensorData> queryDataByDeviceIdAndRoads(String deviceId, Integer roads, String startTimeStr, String endTimeStr, String field) {
+    public List<SensorData> queryDataByDeviceIdAndRoads(String deviceId, Integer roads, String startTimeStr, String endTimeStr, String field, AggregationWindow aggregationWindow) {
         Assert.notNull(deviceId, "deviceId cannot be null");
         Assert.notNull(roads, "roads cannot be null");
         Assert.notNull(startTimeStr, "startTime cannot be null");
@@ -119,14 +120,14 @@ public class JfcloudSensorDataService extends JfcloudFluxDataService<SensorData>
         // 转换为ISO8601格式
         String startTimeFormatted = convertToISO8601(startTimeStr);
         String endTimeFormatted = convertToISO8601(endTimeStr);
-        String aggregationWindow = FluxAggregationUtils.determineAggregationWindow(startTimeFormatted, endTimeFormatted);
+        String aggregationWindowA =aggregationWindow.getCode(); //FluxAggregationUtils.determineAggregationWindow(startTimeFormatted, endTimeFormatted);
         String measurement = "sensor_data"; // 数据表名称
         Map<String, String> filters = Map.of(
                 "device_id", deviceId,
                 "roads", roads.toString()
         );
         // 构建查询语句
-        String query = FluxQueryBuilder.buildRangeQuery(getBucketName(), startTimeFormatted, endTimeFormatted, measurement, field, filters, aggregationWindow);
+        String query = FluxQueryBuilder.buildRangeQuery(getBucketName(), startTimeFormatted, endTimeFormatted, measurement, field, filters, aggregationWindowA);
         QueryApi queryApi = jfcloudInfluxDBService.getInfluxDBClient().getQueryApi();
         List<FluxTable> results = queryApi.query(query);
         return results.stream()

+ 73 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/param/AggregationWindow.java

@@ -0,0 +1,73 @@
+package vip.xiaonuo.coldchain.modular.app.param;
+
+import java.time.Duration;
+import java.time.Instant;
+
+/**
+ * @author jackzhou
+ * @version 1.0
+ * @project jfcloud-coldchain
+ * @description
+ * @date 2024/12/10 15:31:56
+ */
+public enum AggregationWindow {
+    MINUTE("1m", "分钟"),
+    HOUR("1h", "小时"),
+    HALF_DAY("12h", "半天"),
+    DAY("1d", "天"),
+    WEEK("1w", "自然周"),
+    MONTH("1mo", "月度"),
+    YEAR("1y", "年度");
+
+    private final String code;
+    private final String description;
+
+    // 构造函数
+    AggregationWindow(String code, String description) {
+        this.code = code;
+        this.description = description;
+    }
+
+    // 获取聚合窗口的代码
+    public String getCode() {
+        return code;
+    }
+
+    // 获取聚合窗口的描述
+    public String getDescription() {
+        return description;
+    }
+
+    // 根据字符串获取对应的聚合窗口
+    public static AggregationWindow fromString(String window) {
+        for (AggregationWindow aggregationWindow : AggregationWindow.values()) {
+            if (aggregationWindow.code.equals(window)) {
+                return aggregationWindow;
+            }
+        }
+        throw new IllegalArgumentException("Unknown aggregation window: " + window);
+    }
+
+    // 根据时间范围计算推荐的聚合窗口
+    public static AggregationWindow determineAggregationWindow(String startTime, String stopTime) {
+        Instant start = Instant.parse(startTime);
+        Instant stop = Instant.parse(stopTime);
+        Duration duration = Duration.between(start, stop);
+        long days = duration.toDays();
+        if (days >= 365) {
+            return YEAR; // 超过一年,按年度聚合
+        } else if (days >= 30) {
+            return MONTH; // 超过30天,按月度聚合
+        } else if (days >= 7) {
+            return WEEK; // 超过7天,按自然周聚合
+        } else if (days >= 1) {
+            return DAY; // 超过1天,按天聚合
+        } else if (duration.toHours() >= 12) {
+            return HALF_DAY; // 超过半天,按半天聚合
+        } else if (duration.toHours() >= 1) {
+            return HOUR; // 超过1小时,按小时聚合
+        } else {
+            return MINUTE; // 默认按分钟聚合
+        }
+    }
+}

+ 3 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/param/AppDeviceQueryParams.java

@@ -31,4 +31,7 @@ public class AppDeviceQueryParams {
     private String sensorCode;
     private Integer sensorRoute;
 
+    @Schema(description = "聚合维度")
+    private String aggregationWindow;
+
 }

+ 10 - 1
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/service/AppDeviceService.java

@@ -149,6 +149,15 @@ public class AppDeviceService {
 
     public SensorEchartDataResult queryDataByDeviceIdAndRoads(AppDeviceQueryParams appDeviceQueryParams) {
         Assert.notNull(appDeviceQueryParams, "appDeviceQueryParams cannot be null");
+        // 获取用户选择的聚合维度,优先使用用户选择的聚合维度,如果没有选择则根据时间范围计算
+        String aggregationWindow = appDeviceQueryParams.getAggregationWindow();
+        if (StrUtil.isBlank(aggregationWindow)) {
+            aggregationWindow = AggregationWindow.determineAggregationWindow(
+                    appDeviceQueryParams.getStartTime(),
+                    appDeviceQueryParams.getEndTime()).getCode();
+        }
+        // 根据聚合维度获取相应的聚合窗口
+        AggregationWindow window = AggregationWindow.fromString(aggregationWindow);
 
         // 查找监控目标区域
         MonitorTargetRegion monitorTarget = monitorTargetRegionService.findOneByDeviceCodeAndSensorNo(
@@ -186,7 +195,7 @@ public class AppDeviceService {
                         appDeviceQueryParams.getSensorRoute(),
                         appDeviceQueryParams.getStartTime(),
                         appDeviceQueryParams.getEndTime(),
-                        dataType
+                        dataType,window
                 );
 
                 // 处理数据并设置到对应的字段

+ 2 - 1
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitordevice/service/MonitorDeviceService.java

@@ -18,6 +18,7 @@ import com.github.jfcloud.influxdb.flux.QueryCondition;
 import rk.netDevice.sdk.p2.ParamData;
 import rk.netDevice.sdk.p2.ParamIdsData;
 import vip.xiaonuo.coldchain.core.bean.influxdb.SensorData;
+import vip.xiaonuo.coldchain.modular.app.param.AggregationWindow;
 import vip.xiaonuo.coldchain.modular.monitordevice.entity.MonitorDevice;
 import vip.xiaonuo.coldchain.modular.monitordevice.param.MonitorDeviceAddParam;
 import vip.xiaonuo.coldchain.modular.monitordevice.param.MonitorDeviceEditParam;
@@ -94,7 +95,7 @@ public interface MonitorDeviceService extends IService<MonitorDevice> {
 
     boolean updateLastLoginTimeByDeviceId(Integer deviceId, Date timestamp);
 
-    List<SensorData> queryDataByDeviceIdAndRoads(String deviceId, Integer sensorRoute, String startTime, String endTime,String field);
+    List<SensorData> queryDataByDeviceIdAndRoads(String deviceId, Integer sensorRoute, String startTime, String endTime, String field, AggregationWindow aggregationWindow);
 
 
     SensorData queryLatestDataByDeviceIdAndRoads(String deviceId, Integer sensorRoute);

+ 3 - 2
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitordevice/service/impl/MonitorDeviceServiceImpl.java

@@ -34,6 +34,7 @@ import vip.xiaonuo.coldchain.core.bean.influxdb.SensorData;
 import vip.xiaonuo.coldchain.core.cache.monitordevice.MonitorDeviceCache;
 import vip.xiaonuo.coldchain.core.renke.RenKeService;
 import vip.xiaonuo.coldchain.core.service.JfcloudSensorDataService;
+import vip.xiaonuo.coldchain.modular.app.param.AggregationWindow;
 import vip.xiaonuo.coldchain.modular.monitordevice.entity.MonitorDevice;
 import vip.xiaonuo.coldchain.modular.monitordevice.enums.MonitorDeviceStatusEnum;
 import vip.xiaonuo.coldchain.modular.monitordevice.mapper.MonitorDeviceMapper;
@@ -310,8 +311,8 @@ public class MonitorDeviceServiceImpl extends ServiceImpl<MonitorDeviceMapper, M
     }
 
     @Override
-    public List<SensorData> queryDataByDeviceIdAndRoads(String deviceId, Integer roads, String startTime, String endTime, String field) {
-        return sensorDataService.queryDataByDeviceIdAndRoads(deviceId, roads, startTime, endTime,field);
+    public List<SensorData> queryDataByDeviceIdAndRoads(String deviceId, Integer roads, String startTime, String endTime, String field, AggregationWindow aggregationWindow) {
+        return sensorDataService.queryDataByDeviceIdAndRoads(deviceId, roads, startTime, endTime,field,aggregationWindow);
     }
 
     @Override