Browse Source

fix:修复个别传感器记录数据总条数不正确bug
fix:修复微信公众号异常恢复消息无法推送bug
fix:修复查询语句加or导致的数据隔离失效问题
feat:新增传感器数据导出接口

黄渊昊 4 months ago
parent
commit
f048886d4e

+ 4 - 4
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/SensorAlarmServiceImpl.java

@@ -113,11 +113,11 @@ public class SensorAlarmServiceImpl extends ServiceImpl<SensorAlarmMapper, Senso
         queryWrapper.lambda().eq(SensorAlarm::getCreateOrg, orgId);
         final String type = messagePageParam.getType();
         if(StrUtil.isNotBlank(type) && type.trim().equalsIgnoreCase("system")){
-            queryWrapper.lambda().eq(SensorAlarm::getType, SensorAlarmType.SENSOR_OFF_LINE.getDeviceCode())
-                    .or().eq(SensorAlarm::getType, SensorAlarmType.SENSOR_ON_LINE.getDeviceCode());
+            queryWrapper.lambda().and(q -> q.eq(SensorAlarm::getType, SensorAlarmType.SENSOR_OFF_LINE.getDeviceCode())
+                    .or().eq(SensorAlarm::getType, SensorAlarmType.SENSOR_ON_LINE.getDeviceCode()));
         }else{
-            queryWrapper.lambda().eq(SensorAlarm::getType, SensorAlarmType.DATA_ALARM.getDeviceCode())
-                    .or().eq(SensorAlarm::getType, SensorAlarmType.DATA_RESTORE_ALARM.getDeviceCode());
+            queryWrapper.lambda().and(q -> q.eq(SensorAlarm::getType, SensorAlarmType.DATA_ALARM.getDeviceCode())
+                    .or().eq(SensorAlarm::getType, SensorAlarmType.DATA_RESTORE_ALARM.getDeviceCode()));
         }
         if(StrUtil.isNotBlank(messagePageParam.getSensorCode())){
             queryWrapper.lambda().eq(SensorAlarm::getSensorCode, messagePageParam.getSensorCode());

+ 1 - 1
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/impl/WechatMessagePushService.java

@@ -67,7 +67,7 @@ public class WechatMessagePushService implements MessagePushService {
             pushParam.setRecoverCause(alarm.getMessage());
         }
         if (StrUtil.isNotBlank(alarm.getRoomName())) {
-            pushParam.setDeviceName(alarm.getSource() + "(" + alarm.getRoomName() + ")");
+            pushParam.setDeviceName(alarm.getSource());
         } else {
             pushParam.setDeviceName(alarm.getSource());
         }

+ 2 - 1
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/JfcloudSensorDataService.java

@@ -207,6 +207,7 @@ public class JfcloudSensorDataService extends JfcloudFluxDataService<SensorData>
                       |> range(start: %s, stop: %s)
                       |> filter(fn: (r) => r["_measurement"] == "%s")
                       |> filter(fn: (r) => r["device_id"] == "%s" and r["roads"] == "%s")
+                      |> filter(fn: (r) => r["_field"] == "humidity" or r["_field"] == "temperature" or r["_field"] == "battery")
                       |> count()
                     """, getBucketName(), startDate, endDate, JfcloudColdChainConstants.INFLUXDB_DEFAULT_MEASUREMENT_NAME, deviceId, roads);
 
@@ -216,7 +217,7 @@ public class JfcloudSensorDataService extends JfcloudFluxDataService<SensorData>
 
             // 处理查询结果
             if (result != null && !result.isEmpty()) {
-                FluxTable fluxTable = result.get(0);
+                FluxTable fluxTable = result.get(result.size() - 1);
                 if (fluxTable.getRecords() != null && !fluxTable.getRecords().isEmpty()) {
                     // 获取结果值
                     Object countValue = fluxTable.getRecords().get(0).getValues().get("_value");

+ 12 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/controller/AppController.java

@@ -5,12 +5,14 @@ import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.Valid;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 import vip.xiaonuo.coldchain.modular.app.param.*;
+import vip.xiaonuo.coldchain.modular.app.param.export.TrendParam;
 import vip.xiaonuo.coldchain.modular.app.service.AppDeviceService;
 import vip.xiaonuo.coldchain.modular.app.service.MessageService;
 import vip.xiaonuo.common.pojo.CommonResult;
@@ -127,4 +129,14 @@ public class AppController {
     public void markMessagesAsRead(@RequestBody List<Long> messageIds) {
         messageService.markMessagesAsRead(messageIds);
     }
+
+    /**
+     * 导出传感器数据
+     */
+    @Operation(description = "导出传感器数据")
+    @GetMapping("/device/export")
+    public CommonResult<String> export(HttpServletResponse response, TrendParam trendParam) {
+        appDeviceService.export(response,trendParam);
+        return CommonResult.ok();
+    }
 }

+ 31 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/param/export/ExportParam.java

@@ -0,0 +1,31 @@
+package vip.xiaonuo.coldchain.modular.app.param.export;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+@EqualsAndHashCode
+@ColumnWidth(25)
+public class ExportParam {
+    @ExcelProperty("名称")
+    private String regionName;
+
+    @ExcelProperty("传感器编码")
+    private String deviceCode;
+
+    @ExcelProperty("传感器路数")
+    private Integer sensorRoad;
+
+    @ExcelProperty("时间")
+    private String time;
+
+    @ExcelProperty("数据种类")
+    private String dataType;
+
+    @ExcelProperty("测量值")
+    private Float data;
+}

+ 30 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/param/export/TrendParam.java

@@ -0,0 +1,30 @@
+package vip.xiaonuo.coldchain.modular.app.param.export;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+@Getter
+@Setter
+public class TrendParam {
+
+    @Schema(description = "设备编号")
+    private String sensorCode;
+
+    @Schema(description = "传感器路数")
+    private Integer roads;
+
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date startTime;
+
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date endTime;
+
+    private String aggregationWindow;
+}

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

@@ -12,16 +12,23 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.StrUtil;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.support.ExcelTypeEnum;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.github.jfcloud.influxdb.flux.AggregationWindow;
 import com.google.common.collect.Lists;
+import jakarta.servlet.http.HttpServletResponse;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
 import vip.xiaonuo.coldchain.core.bean.influxdb.SensorData;
 import vip.xiaonuo.coldchain.core.service.JfcloudSensorDataService;
 import vip.xiaonuo.coldchain.modular.app.param.*;
+import vip.xiaonuo.coldchain.modular.app.param.export.ExportParam;
+import vip.xiaonuo.coldchain.modular.app.param.export.TrendParam;
+import vip.xiaonuo.coldchain.modular.monitordevice.entity.MonitorDeviceTemplate;
+import vip.xiaonuo.coldchain.modular.monitordevice.handler.CustomCellWriteHandler;
 import vip.xiaonuo.coldchain.modular.monitordevice.service.MonitorDeviceService;
 import vip.xiaonuo.coldchain.modular.monitortarget.entity.MonitorTarget;
 import vip.xiaonuo.coldchain.modular.monitortarget.param.MonitorTargetPageParam;
@@ -31,6 +38,10 @@ import vip.xiaonuo.coldchain.modular.monitortargetregion.entity.MonitorTargetReg
 import vip.xiaonuo.coldchain.modular.monitortargetregion.service.MonitorTargetRegionService;
 import vip.xiaonuo.common.enums.CommonDeleteFlagEnum;
 
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
@@ -430,4 +441,64 @@ public class AppDeviceService {
         monitorTargetRegion.setDeviceOfflineAlarm(appDeviceAlarmParam.getDeviceOfflineAlarm());
         return monitorTargetRegionService.updateById(monitorTargetRegion);
     }
+
+    public void export(HttpServletResponse response, TrendParam trendParam) {
+        AppDeviceQueryParams appDeviceQueryParams = BeanUtil.copyProperties(trendParam, AppDeviceQueryParams.class);
+        SensorEchartDataResult sensorEchartDataResult = queryDataByDeviceIdAndRoads(appDeviceQueryParams);
+        MonitorTargetRegion monitorTargetRegion = monitorTargetRegionService.findOneByDeviceCodeAndSensorNo(trendParam.getSensorCode(), trendParam.getRoads());
+        List<ExportParam> exportParamList = new ArrayList<>();
+        ExportParam exportParam = new ExportParam();
+        exportParam.setRegionName(monitorTargetRegion.getName());
+        exportParam.setDeviceCode(trendParam.getSensorCode());
+        exportParam.setSensorRoad(trendParam.getRoads());
+        List<String> list = List.of(Arrays.toString(monitorTargetRegion.getSensorType().toCharArray()));
+        if (list.contains("W")) {
+            exportParam.setDataType("温度");
+            LinkedHashSet<String> x = sensorEchartDataResult.getTemperature().getX();
+            List<Float> y = sensorEchartDataResult.getTemperature().getY();
+            int i = 0;
+            for (String s : x) {
+                exportParam.setTime(s);
+                exportParam.setData(y.get(i));
+                i++;
+                exportParamList.add(exportParam);
+            }
+        } else if (list.contains("S")) {
+            exportParam.setDataType("湿度");
+            LinkedHashSet<String> x = sensorEchartDataResult.getHumidity().getX();
+            List<Float> y = sensorEchartDataResult.getHumidity().getY();
+            int i = 0;
+            for (String s : x) {
+                exportParam.setTime(s);
+                exportParam.setData(y.get(i));
+                i++;
+                exportParamList.add(exportParam);
+            }
+        } else if (list.contains("C")) {
+            exportParam.setDataType("二氧化碳浓度");
+            LinkedHashSet<String> x = sensorEchartDataResult.getCo2().getX();
+            List<Float> y = sensorEchartDataResult.getCo2().getY();
+            int i = 0;
+            for (String s : x) {
+                exportParam.setTime(s);
+                exportParam.setData(y.get(i));
+                i++;
+                exportParamList.add(exportParam);
+            }
+        }
+        String fileName = "传感器数据";
+        String sheetName = "传感器数据";
+        response.setContentType("application/vnd.ms-excel");
+        response.setCharacterEncoding("utf-8");
+
+        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + URLEncoder.encode(fileName, StandardCharsets.UTF_8) + ".xls");
+        try (OutputStream outputStream = response.getOutputStream()) {
+            EasyExcel.write(outputStream, MonitorDeviceTemplate.class)
+                    .excelType(ExcelTypeEnum.XLS)
+                    .sheet(sheetName)
+                    .doWrite(exportParamList);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
 }

+ 1 - 1
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitorsearchhistory/service/impl/SearchHistoryServiceImpl.java

@@ -32,7 +32,7 @@ public class SearchHistoryServiceImpl extends ServiceImpl<SearchHistoryMapper, S
                 .eq(SearchHistory::getDeleteFlag, CommonDeleteFlagEnum.NOT_DELETE)
                 .groupBy(SearchHistory::getSearchKey)
                 .orderByDesc(SearchHistory::getCreateTime)
-                .last("limit 10");
+                .last("limit 20");
         return list(queryWrapper);
     }