From ec1c5d7c11ba26fa537eb8ba3b83186ea677d69e Mon Sep 17 00:00:00 2001 From: George Date: Mon, 2 Feb 2026 23:01:17 +0800 Subject: [PATCH] =?UTF-8?q?20260102=EF=BC=9A1=E3=80=81=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=BF=AE=E5=A4=8D=E9=A1=B5=E9=9D=A2=EF=BC=8C?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=87=AA=E5=8A=A8=E4=BF=AE=E5=A4=8D=E4=B8=8E?= =?UTF-8?q?=E6=89=8B=E5=8A=A8=E4=BF=AE=E5=A4=8D=EF=BC=88B=E4=B8=8E(A+C)/2?= =?UTF-8?q?=E7=9A=84=E5=B7=AE=E5=80=BC=E8=B6=85=E8=BF=8730%=EF=BC=89?= =?UTF-8?q?=EF=BC=9B=202=E3=80=81=E8=AE=BE=E5=A4=87=E7=AE=A1=E7=90=86-?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E8=B0=83=E8=AF=95=E9=A1=B5=E9=9D=A2=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E6=95=B0=E6=8D=AE=E5=BC=B9=E6=A1=86=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=8B=96=E5=8A=A8=EF=BC=9B=203=E3=80=81=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=96=B0=E5=BB=BA=E4=BA=A7=E5=93=81=E6=8C=87=E4=BB=A4=EF=BC=8C?= =?UTF-8?q?=E5=9C=A8=E4=BA=A7=E5=93=81=E4=BB=BB=E6=84=8F=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E4=B8=8B=E9=83=BD=E5=8F=AF=E6=96=B0=E5=BB=BA=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E6=8C=87=E4=BB=A4=EF=BC=8C=E6=96=B0=E5=BB=BA=E4=B9=8B=E5=90=8E?= =?UTF-8?q?=E6=89=80=E5=B1=9E=E6=9C=89=E8=AE=BE=E5=A4=87=E9=83=BD=E8=83=BD?= =?UTF-8?q?=E7=9C=8B=E5=88=B0=E8=AF=A5=E4=BA=A7=E5=93=81=E6=8C=87=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/constant/FastBeeConstant.java | 6 + .../fastbee/common/enums/ThingsModelType.java | 2 +- .../com/fastbee/common/utils/DateUtils.java | 92 +- .../deviceLog/DataRepairController.java | 132 ++ .../com/fastbee/json/JsonProtocolService.java | 2 +- .../jsonPak/JsonPakProtocolService.java | 2 +- .../jsonchenyi/JsonChenYiProtocolService.java | 2 +- .../com/fastbee/iot/domain/ThingsModel.java | 10 +- .../fastbee/iot/mapper/DeviceLogMapper.java | 3 + .../fastbee/iot/mapper/TDDeviceLogMapper.java | 2 + .../iot/model/param/DataRepairQueryParam.java | 59 + .../iot/service/IDataRepairService.java | 127 ++ .../service/impl/DataCenterServiceImpl.java | 3 +- .../service/impl/DataRepairServiceImpl.java | 349 +++++ .../service/impl/DeviceLogServiceImpl.java | 18 +- .../iot/service/impl/DeviceServiceImpl.java | 8 +- .../service/impl/ThingsModelServiceImpl.java | 18 - .../iot/tdengine/service/ILogService.java | 2 + .../service/impl/MySqlLogServiceImpl.java | 6 + .../service/impl/TdengineLogServiceImpl.java | 5 + .../resources/mapper/iot/DeviceLogMapper.xml | 17 + .../mapper/iot/TDDeviceLogMapper.xml | 15 + sql/yack.sql | 4 + vue/package-lock.json | 947 ++++++------- vue/src/api/data/repair.js | 132 ++ vue/src/assets/icons/svg/data-analysis.svg | 1 + vue/src/router/index.js | 7 + vue/src/views/dataCenter/dataRepair.vue | 1207 +++++++++++++++++ .../views/iot/device/instruction-parsing.vue | 2 +- 29 files changed, 2574 insertions(+), 606 deletions(-) create mode 100644 fastbee-open-api/src/main/java/com/fastbee/controller/deviceLog/DataRepairController.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/param/DataRepairQueryParam.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/IDataRepairService.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DataRepairServiceImpl.java create mode 100644 vue/src/api/data/repair.js create mode 100644 vue/src/assets/icons/svg/data-analysis.svg create mode 100644 vue/src/views/dataCenter/dataRepair.vue diff --git a/fastbee-common/src/main/java/com/fastbee/common/constant/FastBeeConstant.java b/fastbee-common/src/main/java/com/fastbee/common/constant/FastBeeConstant.java index e452b7a6..ea44ca72 100644 --- a/fastbee-common/src/main/java/com/fastbee/common/constant/FastBeeConstant.java +++ b/fastbee-common/src/main/java/com/fastbee/common/constant/FastBeeConstant.java @@ -291,6 +291,12 @@ public interface FastBeeConstant { */ String POWER_ON_TRIGGER_KEY_PREFIX = "power_on:trigger:"; + /** + * 数据修复配置缓存key + */ + String DATA_REPAIR_CONFIG_KEY = "data:repair:config"; + + } interface PROTOCOL { diff --git a/fastbee-common/src/main/java/com/fastbee/common/enums/ThingsModelType.java b/fastbee-common/src/main/java/com/fastbee/common/enums/ThingsModelType.java index af3f39cf..9e2c5945 100644 --- a/fastbee-common/src/main/java/com/fastbee/common/enums/ThingsModelType.java +++ b/fastbee-common/src/main/java/com/fastbee/common/enums/ThingsModelType.java @@ -13,7 +13,7 @@ import lombok.Getter; public enum ThingsModelType { PROP(1, "PROPERTY", "属性", "properties"), - SERVICE(2, "FUNCTION", "服务", "functions"), + SERVICE(2, "FUNCTION", "服务", "functions"), // 前端页面:功能 EVENT(3, "EVENT", "事件", "events"), ; diff --git a/fastbee-common/src/main/java/com/fastbee/common/utils/DateUtils.java b/fastbee-common/src/main/java/com/fastbee/common/utils/DateUtils.java index f2830059..fe45cd7e 100644 --- a/fastbee-common/src/main/java/com/fastbee/common/utils/DateUtils.java +++ b/fastbee-common/src/main/java/com/fastbee/common/utils/DateUtils.java @@ -14,8 +14,7 @@ import java.util.Random; * * @author ruoyi */ -public class DateUtils extends org.apache.commons.lang3.time.DateUtils -{ +public class DateUtils extends org.apache.commons.lang3.time.DateUtils { public static String YYYY = "yyyy"; public static String YYYY_MM = "yyyy-MM"; @@ -42,8 +41,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils * * @return Date() 当前日期 */ - public static Date getNowDate() - { + public static Date getNowDate() { return new Date(); } @@ -52,44 +50,44 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils * * @return String */ - public static String getDate() - { + public static String getDate() { return dateTimeNow(YYYY_MM_DD); } - public static final String getTime() - { + /** + * 获取昨天的当前时间 + */ + public static String getYesterdayDateTime() { + return parseDateToStr(YYYY_MM_DD_HH_MM_SS, new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000)); + } + + /** + * 获取当前时间 + */ + public static final String getTime() { return dateTimeNow(YYYY_MM_DD_HH_MM_SS); } - public static final String dateTimeNow() - { + public static final String dateTimeNow() { return dateTimeNow(YYYYMMDDHHMMSS); } - public static final String dateTimeNow(final String format) - { + public static final String dateTimeNow(final String format) { return parseDateToStr(format, new Date()); } - public static final String dateTime(final Date date) - { + public static final String dateTime(final Date date) { return parseDateToStr(YYYY_MM_DD, date); } - public static final String parseDateToStr(final String format, final Date date) - { + public static final String parseDateToStr(final String format, final Date date) { return new SimpleDateFormat(format).format(date); } - public static final Date dateTime(final String format, final String ts) - { - try - { + public static final Date dateTime(final String format, final String ts) { + try { return new SimpleDateFormat(format).parse(ts); - } - catch (ParseException e) - { + } catch (ParseException e) { throw new RuntimeException(e); } } @@ -97,8 +95,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils /** * 日期路径 即年/月/日 如2018/08/08 */ - public static final String datePath() - { + public static final String datePath() { Date now = new Date(); return DateFormatUtils.format(now, "yyyy/MM/dd"); } @@ -106,8 +103,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils /** * 日期路径 即年/月/日 如20180808 */ - public static final String dateTime() - { + public static final String dateTime() { Date now = new Date(); return DateFormatUtils.format(now, "yyyyMMdd"); } @@ -116,26 +112,20 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils /** * 日期路径 即年/月/日 如20180808 */ - public static final String dateTimeYY(Date date) - { + public static final String dateTimeYY(Date date) { return DateFormatUtils.format(date, YY_MM_DD_HH_MM_SS); } /** * 日期型字符串转化为日期 格式 */ - public static Date parseDate(Object str) - { - if (str == null) - { + public static Date parseDate(Object str) { + if (str == null) { return null; } - try - { + try { return parseDate(str.toString(), parsePatterns); - } - catch (ParseException e) - { + } catch (ParseException e) { return null; } } @@ -143,8 +133,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils /** * 获取服务器启动时间 */ - public static Date getServerStartDate() - { + public static Date getServerStartDate() { long time = ManagementFactory.getRuntimeMXBean().getStartTime(); return new Date(time); } @@ -152,24 +141,21 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils /** * 计算相差天数 */ - public static int differentDaysByMillisecond(Date date1, Date date2) - { + public static int differentDaysByMillisecond(Date date1, Date date2) { return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24))); } /** * 计算相差秒数 */ - public static int differentSeconds(Date date1, Date date2) - { + public static int differentSeconds(Date date1, Date date2) { return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000))); } /** * 计算两个时间差 */ - public static String getDatePoor(Date endDate, Date nowDate) - { + public static String getDatePoor(Date endDate, Date nowDate) { long nd = 1000 * 24 * 60 * 60; long nh = 1000 * 60 * 60; long nm = 1000 * 60; @@ -190,8 +176,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils /** * 增加 LocalDateTime ==> Date */ - public static Date toDate(LocalDateTime temporalAccessor) - { + public static Date toDate(LocalDateTime temporalAccessor) { ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault()); return Date.from(zdt.toInstant()); } @@ -199,19 +184,18 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils /** * 增加 LocalDate ==> Date */ - public static Date toDate(LocalDate temporalAccessor) - { + public static Date toDate(LocalDate temporalAccessor) { LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0)); ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault()); return Date.from(zdt.toInstant()); } - public static long getTimestamp(){ + public static long getTimestamp() { return System.currentTimeMillis(); } - public static long getTimestampSeconds(){ - return System.currentTimeMillis()/1000; + public static long getTimestampSeconds() { + return System.currentTimeMillis() / 1000; } public static String generateRandomHex(int length) { @@ -239,6 +223,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils /** * 字符串去除毫秒 + * * @param time 时间字符串 * @return java.lang.String */ @@ -249,6 +234,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils /** * 日期去除毫秒 + * * @param time 时间 * @return java.util.Date */ diff --git a/fastbee-open-api/src/main/java/com/fastbee/controller/deviceLog/DataRepairController.java b/fastbee-open-api/src/main/java/com/fastbee/controller/deviceLog/DataRepairController.java new file mode 100644 index 00000000..3d1216e8 --- /dev/null +++ b/fastbee-open-api/src/main/java/com/fastbee/controller/deviceLog/DataRepairController.java @@ -0,0 +1,132 @@ +package com.fastbee.controller.deviceLog; + +/** +* @description: +* @author Sumuxi +* @date 2026/2/1 +*/ + +import com.fastbee.common.annotation.Log; +import com.fastbee.common.core.controller.BaseController; +import com.fastbee.common.core.domain.AjaxResult; +import com.fastbee.common.core.page.TableDataInfo; +import com.fastbee.common.enums.BusinessType; +import com.fastbee.common.utils.StringUtils; +import com.fastbee.iot.domain.DeviceLog; +import com.fastbee.iot.model.param.DataRepairQueryParam; +import com.fastbee.iot.service.IDataRepairService; +import com.fastbee.iot.service.IDeviceLogService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; + +/** + * @description: + * + * @author Sumuxi + * @date 2026/2/1 + */ +@Api(tags = "设备日志模块") +@RestController +@RequestMapping("/iot/dataRepair") +public class DataRepairController extends BaseController { + + @Resource + private IDataRepairService dataRepairService; + + @Resource + private IDeviceLogService deviceLogService; + + @ApiOperation("批量查询设备日志(用于数据校准)") + @PreAuthorize("@ss.hasAnyPermi('iot:device:list,dataCenter:repair:list')") + @GetMapping("/dataRepairList") + public TableDataInfo dataRepairList(DataRepairQueryParam queryParam) { + if (StringUtils.isNotEmpty(queryParam.getSerialNumber())) { + queryParam.setSerialNumber(queryParam.getSerialNumber().toUpperCase()); + } + + List dataRepairList = dataRepairService.getDataRepairList(queryParam); + return getDataTable(dataRepairList); + } + + @ApiOperation("删除指定时间点的所有数据") + @PreAuthorize("@ss.hasAnyPermi('iot:device:edit,dataCenter:repair:list')") + @Log(title = "删除时间点数据", businessType = BusinessType.DELETE) + @DeleteMapping("/deleteByTime") + public AjaxResult deleteDataRepairByTime(@RequestParam String serialNumber, @RequestParam String createTime) { + if (StringUtils.isNotEmpty(serialNumber)) { + serialNumber = serialNumber.toUpperCase(); + } + int deletedCount = dataRepairService.deleteDataRepairByTime(serialNumber, createTime); + return AjaxResult.success("成功删除 " + deletedCount + " 条数据"); + } + + /** + * 批量修改设备日志(数据修复) + */ + @ApiOperation("批量修改设备日志") + @PreAuthorize("@ss.hasAnyPermi('iot:device:edit,dataCenter:repair:list')") + @Log(title = "设备日志批量修复", businessType = BusinessType.UPDATE) + @PostMapping("/batchUpdate") + public AjaxResult batchUpdate(@RequestBody List deviceLogList) { + int successCount = 0; + for (DeviceLog deviceLog : deviceLogList) { + try { + int result = deviceLogService.updateDeviceLog(deviceLog); + if (result > 0) { + successCount++; + } + } catch (Exception e) { + // 单条更新失败不影响其他记录 + } + } + return AjaxResult.success("成功更新 " + successCount + " 条数据"); + } + + // 自动校准配置 + /** + * 获取自动校准配置列表 + */ + @ApiOperation("获取自动校准配置列表") + @PreAuthorize("@ss.hasAnyPermi('iot:device:list,dataCenter:repair:list')") + @GetMapping("/autoCalibration/config") + public AjaxResult getDataRepairConfig() { + List configs = dataRepairService.getAllDataRepairConfigs(); + return AjaxResult.success(configs); + } + + /** + * 添加数据修复配置 + */ + @ApiOperation("添加自动校准配置") + @PreAuthorize("@ss.hasAnyPermi('iot:device:edit,dataCenter:repair:list')") + @Log(title = "自动校准配置", businessType = BusinessType.INSERT) + @PostMapping("/autoCalibration/config") + public AjaxResult addAutoCalibrationConfig(@RequestBody Map params) { + Long deviceId = Long.valueOf(params.get("deviceId").toString()); + String serialNumber = params.get("serialNumber").toString(); + String deviceName = params.get("deviceName").toString(); + String identifier = params.get("identifier").toString(); + String modelName = params.get("modelName").toString(); + + dataRepairService.addDataRepairConfig(deviceId, serialNumber, deviceName, identifier, modelName); + return AjaxResult.success(); + } + + /** + * 删除数据修复配置 + */ + @ApiOperation("删除自动校准配置") + @PreAuthorize("@ss.hasAnyPermi('iot:device:edit,dataCenter:repair:list')") + @Log(title = "数据修复配置", businessType = BusinessType.DELETE) + @DeleteMapping("/autoCalibration/config") + public AjaxResult removeAutoCalibrationConfig(@RequestParam String serialNumber, @RequestParam String identifier) { + dataRepairService.removeDataRepairConfig(serialNumber, identifier); + return AjaxResult.success(); + } +} diff --git a/fastbee-protocol/fastbee-protocol-collect/src/main/java/com/fastbee/json/JsonProtocolService.java b/fastbee-protocol/fastbee-protocol-collect/src/main/java/com/fastbee/json/JsonProtocolService.java index 32971503..a67c99e4 100644 --- a/fastbee-protocol/fastbee-protocol-collect/src/main/java/com/fastbee/json/JsonProtocolService.java +++ b/fastbee-protocol/fastbee-protocol-collect/src/main/java/com/fastbee/json/JsonProtocolService.java @@ -46,7 +46,7 @@ public class JsonProtocolService implements IProtocol { public DeviceReport decode(DeviceData deviceData, String clientId) { try { DeviceReport reportMessage = new DeviceReport(); - // bytep[] 转String + // byte[] 转String String data = new String(deviceData.getData(), StandardCharsets.UTF_8); List values = JSON.parseArray(data, ThingsModelSimpleItem.class); //上报数据时间 diff --git a/fastbee-protocol/fastbee-protocol-collect/src/main/java/com/fastbee/jsonPak/JsonPakProtocolService.java b/fastbee-protocol/fastbee-protocol-collect/src/main/java/com/fastbee/jsonPak/JsonPakProtocolService.java index 9f04b7a6..10a90564 100644 --- a/fastbee-protocol/fastbee-protocol-collect/src/main/java/com/fastbee/jsonPak/JsonPakProtocolService.java +++ b/fastbee-protocol/fastbee-protocol-collect/src/main/java/com/fastbee/jsonPak/JsonPakProtocolService.java @@ -41,7 +41,7 @@ public class JsonPakProtocolService implements IProtocol { public DeviceReport decode(DeviceData deviceData, String clientId) { try { DeviceReport reportMessage = new DeviceReport(); - // bytep[] 转String + // byte[] 转String String data = new String(deviceData.getData(), StandardCharsets.UTF_8); JSONObject params = JSONObject.parseObject(data); List result = new ArrayList<>(); diff --git a/fastbee-protocol/fastbee-protocol-collect/src/main/java/com/fastbee/jsonchenyi/JsonChenYiProtocolService.java b/fastbee-protocol/fastbee-protocol-collect/src/main/java/com/fastbee/jsonchenyi/JsonChenYiProtocolService.java index 65ede434..9c70bda0 100644 --- a/fastbee-protocol/fastbee-protocol-collect/src/main/java/com/fastbee/jsonchenyi/JsonChenYiProtocolService.java +++ b/fastbee-protocol/fastbee-protocol-collect/src/main/java/com/fastbee/jsonchenyi/JsonChenYiProtocolService.java @@ -38,7 +38,7 @@ public class JsonChenYiProtocolService implements IProtocol { public DeviceReport decode(DeviceData deviceData, String clientId) { try { DeviceReport reportMessage = new DeviceReport(); - // bytep[] 转String + // byte[] 转String String data = new String(deviceData.getData(), StandardCharsets.UTF_8); Map values = JSON.parseObject(data, Map.class); JSONArray array = (JSONArray) values.get("data"); diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/domain/ThingsModel.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/domain/ThingsModel.java index 5a25dd40..da8c18e5 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/domain/ThingsModel.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/domain/ThingsModel.java @@ -182,14 +182,22 @@ public class ThingsModel extends BaseEntity { @Excel(name = "是否只读", prompt = "0=否,1=是") private Integer isReadonly; - + /** + * 模型顺序 + */ private Integer modelOrder; + /** + * Modbus配置 + */ private ModbusConfig modbusConfig; @Deprecated private String language; + /** + * 物模型ID列表 + */ private List modelIdList; } diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/mapper/DeviceLogMapper.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/mapper/DeviceLogMapper.java index e2bc10bb..cf9a7145 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/mapper/DeviceLogMapper.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/mapper/DeviceLogMapper.java @@ -46,6 +46,9 @@ public interface DeviceLogMapper { */ public List selectDeviceLogList(DeviceLog deviceLog); + + List getDataRepairList(DeviceLog deviceLog); + /** * 查询设备监测数据 * diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/mapper/TDDeviceLogMapper.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/mapper/TDDeviceLogMapper.java index a1365796..1b952ba5 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/mapper/TDDeviceLogMapper.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/mapper/TDDeviceLogMapper.java @@ -75,6 +75,8 @@ public interface TDDeviceLogMapper { */ List selectDeviceLogList(@Param("database") String database, @Param("device") DeviceLog deviceLog); + List getDataRepairList(String dbName, DeviceLog deviceLog); + /*** * 根据设备ID删除设备日志 */ diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/param/DataRepairQueryParam.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/param/DataRepairQueryParam.java new file mode 100644 index 00000000..6c3eae61 --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/param/DataRepairQueryParam.java @@ -0,0 +1,59 @@ +package com.fastbee.iot.model.param; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @description: 数据修复查询DTO + * @author Sumuxi + * @date 2026/2/1 + */ + +@Data +@ApiModel(value = "DataRepairQueryParam", description = "数据修复查询参数") +public class DataRepairQueryParam { + + /** + * 设备编号 + */ + @ApiModelProperty("设备编号") + private String serialNumber; + + /** + * 标识符 + */ + @ApiModelProperty("标识符") + private String identity; + + /** + * 产品ID + */ + @ApiModelProperty("产品ID") + private Long productId; + + /** + * 开始时间 + */ + @ApiModelProperty("开始时间") + private String beginTime; + + /** + * 结束时间 + */ + @ApiModelProperty("结束时间") + private String endTime; + + /** + * 页码 + */ + @ApiModelProperty("页码") + private Integer pageNum; + + /** + * 每页大小 + */ + @ApiModelProperty("每页大小") + private Integer pageSize; +} + diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/IDataRepairService.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/IDataRepairService.java new file mode 100644 index 00000000..ced6938c --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/IDataRepairService.java @@ -0,0 +1,127 @@ +package com.fastbee.iot.service; + +import com.fastbee.iot.domain.DeviceLog; +import com.fastbee.iot.model.param.DataRepairQueryParam; +import java.util.List; + +/** + * @description: 数据修复服务接口 + * @author Sumuxi + * @date 2026/2/1 + */ +public interface IDataRepairService { + + + /** + * 获取数据修复列表 + * + * @param queryParam 查询参数 + * @return 设备日志列表 + */ + List getDataRepairList(DataRepairQueryParam queryParam); + + /** + * 添加数据修复配置 + * + * @param deviceId 设备ID + * @param serialNumber 设备编号 + * @param deviceName 设备名称 + * @param identifier 物模型标识符 + * @param modelName 物模型名称 + */ + void addDataRepairConfig(Long deviceId, String serialNumber, String deviceName, String identifier, String modelName); + + /** + * 删除数据修复配置 + * + * @param serialNumber 设备编号 + * @param identifier 物模型标识符 + */ + void removeDataRepairConfig(String serialNumber, String identifier); + + /** + * 获取所有数据修复配置 + * + * @return 配置列表 + */ + List getAllDataRepairConfigs(); + + /** + * 检查是否需要数据修复 + * + * @param serialNumber 设备编号 + * @param identifier 物模型标识符 + * @return 是否需要修复 + */ + boolean needDataRepair(String serialNumber, String identifier); + + /** + * 执行数据修复 + * + * @param serialNumber 设备编号 + * @param isShadow 是否为影子数据 + * @param currentLogs 当前上报的日志 + */ + void executeDataRepair(String serialNumber, boolean isShadow, List currentLogs); + + /** + * 根据时间删除数据修复记录 + * + * @param serialNumber 设备编号 + * @param createTime 创建时间 + * @return 删除数量 + */ + int deleteDataRepairByTime(String serialNumber, String createTime); + + /** + * 数据修复配置实体 + */ + class DataRepairConfig { + private Long deviceId; + private String serialNumber; + private String deviceName; + private String identifier; + private String modelName; + + public Long getDeviceId() { + return deviceId; + } + + public void setDeviceId(Long deviceId) { + this.deviceId = deviceId; + } + + public String getSerialNumber() { + return serialNumber; + } + + public void setSerialNumber(String serialNumber) { + this.serialNumber = serialNumber; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public String getModelName() { + return modelName; + } + + public void setModelName(String modelName) { + this.modelName = modelName; + } + } +} + diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DataCenterServiceImpl.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DataCenterServiceImpl.java index 90f68a1b..10a4afd5 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DataCenterServiceImpl.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DataCenterServiceImpl.java @@ -75,8 +75,7 @@ public class DataCenterServiceImpl implements DataCenterService { deviceLog.setSerialNumber(deviceHistoryParam.getSerialNumber()); deviceLog.setBeginTime(deviceHistoryParam.getBeginTime()); deviceLog.setEndTime(deviceHistoryParam.getEndTime()); - List historyModelList1 = deviceLogService.listHistory(deviceLog); - historyModelList.addAll(historyModelList1); + historyModelList.addAll(deviceLogService.listHistory(deviceLog)); } List functionIdentifierList = identifierVOList.stream().filter(t -> 2 == t.getType()).map(DeviceHistoryParam.IdentifierVO::getIdentifier).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(functionIdentifierList)) { diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DataRepairServiceImpl.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DataRepairServiceImpl.java new file mode 100644 index 00000000..f7a43b12 --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DataRepairServiceImpl.java @@ -0,0 +1,349 @@ +package com.fastbee.iot.service.impl; + +import com.alibaba.fastjson2.JSON; +import com.fastbee.common.constant.FastBeeConstant; +import com.fastbee.common.utils.DateUtils; +import com.fastbee.iot.domain.DeviceLog; +import com.fastbee.iot.model.DeviceHistoryParam; +import com.fastbee.iot.model.HistoryModel; +import com.fastbee.iot.model.param.DataRepairQueryParam; +import com.fastbee.iot.model.dto.ThingsModelDTO; +import com.fastbee.iot.service.IDataRepairService; +import com.fastbee.iot.service.IDeviceLogService; +import com.fastbee.iot.service.IThingsModelService; +import com.fastbee.iot.tdengine.service.ILogService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @description: 数据修复服务实现 + * @author Sumuxi + * @date 2026/2/1 + */ +@Service +@Slf4j +public class DataRepairServiceImpl implements IDataRepairService { + + private static final double REPAIR_THRESHOLD = 0.3; // 30%阈值 + + @Resource + private IDeviceLogService deviceLogService; + + @Resource + private IThingsModelService thingsModelService; + + @Resource + private ILogService logService; + + @Resource + private RedisTemplate redisTemplate; + + @Override + public List getDataRepairList(DataRepairQueryParam queryParam) { + + // 使用productId查询物模型 + List list = thingsModelService.getCacheAndHandleArrayByProductId(queryParam.getProductId(), + queryParam.getSerialNumber()); + List identifierVOList = new ArrayList<>(); + for (ThingsModelDTO thingsModelDTO : list) { + DeviceHistoryParam.IdentifierVO identifierVO = new DeviceHistoryParam.IdentifierVO(); + identifierVO.setIdentifier(thingsModelDTO.getIdentifier()); + identifierVO.setType(thingsModelDTO.getType()); + identifierVOList.add(identifierVO); + } + + // 获取所有标识符的时间-去重 + Set dateTreeSet = new TreeSet<>(); + List identifierList = identifierVOList.stream() + .map(DeviceHistoryParam.IdentifierVO::getIdentifier) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(identifierList)) { + DeviceLog deviceLogParam = new DeviceLog(); + deviceLogParam.setIdentityList(identifierList); + deviceLogParam.setSerialNumber(queryParam.getSerialNumber()); + deviceLogParam.setBeginTime(queryParam.getBeginTime()); + deviceLogParam.setEndTime(queryParam.getEndTime()); + List historyModels = logService.listHistory(deviceLogParam); + dateTreeSet.addAll(historyModels.stream().map(HistoryModel::getTime).collect(Collectors.toList())); + } + + // 将DTO转换为DeviceLog对象 + DeviceLog deviceLog = new DeviceLog(); + deviceLog.setSerialNumber(queryParam.getSerialNumber()); + deviceLog.setIdentity(queryParam.getIdentity()); + deviceLog.setBeginTime(queryParam.getBeginTime()); + deviceLog.setEndTime(queryParam.getEndTime()); + Map createTimeMap = logService.getDataRepairList(deviceLog).stream() + .collect(Collectors.toMap(DeviceLog::getCreateTime, Function.identity(), (v1, v2) -> v1)); + List dataRepairList = new ArrayList<>(); + for (Date date : dateTreeSet) { + if (createTimeMap.containsKey(date) && Objects.equals(date, createTimeMap.get(date).getCreateTime())) { + dataRepairList.add(createTimeMap.get(date)); + } else { + DeviceLog deviceLogTemp = new DeviceLog(); + deviceLogTemp.setSerialNumber(queryParam.getSerialNumber()); + deviceLogTemp.setCreateTime(date); + deviceLogTemp.setIdentity(queryParam.getIdentity()); + dataRepairList.add(deviceLogTemp); + } + } + return dataRepairList; + } + + @Override + public int deleteDataRepairByTime(String serialNumber, String createTime) { + try { + // 解析时间字符串 + Date date = DateUtils.parseDate(createTime); + if (date == null) { + log.warn("时间格式错误: createTime={}", createTime); + return 0; + } + + + // 查询该时间点附近的所有数据 + DeviceLog queryLog = new DeviceLog(); + queryLog.setSerialNumber(serialNumber); + queryLog.setCreateTime(date); + List logsNearTime = logService.getDataRepairList(queryLog); + + if (CollectionUtils.isEmpty(logsNearTime)) { + log.info("该时间点无数据: serialNumber={}, createTime={}", serialNumber, createTime); + return 0; + } + + // 批量删除 + Long[] logIds = logsNearTime.stream() + .map(DeviceLog::getLogId) + .filter(Objects::nonNull) + .toArray(Long[]::new); + + if (logIds.length > 0) { + int deletedCount = deviceLogService.deleteDeviceLogByLogIds(logIds); + log.info("删除时间点数据成功: serialNumber={}, createTime={}, 删除记录数={}", serialNumber, createTime, deletedCount); + return deletedCount; + } + + return 0; + } catch (Exception e) { + log.error("删除时间点数据失败: serialNumber={}, createTime={}", serialNumber, createTime, e); + return 0; + } + } + + @Override + public void addDataRepairConfig(Long deviceId, String serialNumber, String deviceName, String identifier, + String modelName) { + IDataRepairService.DataRepairConfig config = new IDataRepairService.DataRepairConfig(); + config.setDeviceId(deviceId); + config.setSerialNumber(serialNumber); + config.setDeviceName(deviceName); + config.setIdentifier(identifier); + config.setModelName(modelName); + + // 大Key代表整个业务,hashKey为"设备:物模型",每个配置独立存储 + String hashKey = buildDeviceIdentifierKey(serialNumber, identifier); + redisTemplate.opsForHash().put(FastBeeConstant.REDIS.DATA_REPAIR_CONFIG_KEY, hashKey, + JSON.toJSONString(config)); + log.info("添加数据修复配置: serialNumber={}, identifier={}", serialNumber, identifier); + } + + @Override + public void removeDataRepairConfig(String serialNumber, String identifier) { + // 直接删除对应的hashKey + String hashKey = buildDeviceIdentifierKey(serialNumber, identifier); + Long deleted = redisTemplate.opsForHash().delete(FastBeeConstant.REDIS.DATA_REPAIR_CONFIG_KEY, hashKey); + if (deleted != null && deleted > 0) { + log.info("删除数据修复配置: serialNumber={}, identifier={}", serialNumber, identifier); + } else { + log.warn("数据修复配置不存在: serialNumber={}, identifier={}", serialNumber, identifier); + } + } + + @Override + public List getAllDataRepairConfigs() { + // 获取所有hashKey,批量查询所有配置 + Set hashKeys = redisTemplate.opsForHash().keys(FastBeeConstant.REDIS.DATA_REPAIR_CONFIG_KEY); + List configs = new ArrayList<>(); + + if (hashKeys != null && !hashKeys.isEmpty()) { + // 批量获取所有配置值 + List values = redisTemplate.opsForHash().multiGet(FastBeeConstant.REDIS.DATA_REPAIR_CONFIG_KEY, + new ArrayList<>(hashKeys)); + if (values != null) { + for (Object value : values) { + if (value != null) { + try { + IDataRepairService.DataRepairConfig config = JSON.parseObject(value.toString(), + IDataRepairService.DataRepairConfig.class); + configs.add(config); + } catch (Exception e) { + log.warn("解析数据修复配置失败: value={}", value, e); + } + } + } + } + } + + return configs.stream() + .sorted(Comparator.comparing(IDataRepairService.DataRepairConfig::getSerialNumber)) + .collect(Collectors.toList()); + } + + @Override + public boolean needDataRepair(String serialNumber, String identifier) { + // 直接通过hashKey判断配置是否存在 + String hashKey = buildDeviceIdentifierKey(serialNumber, identifier); + return redisTemplate.opsForHash().hasKey(FastBeeConstant.REDIS.DATA_REPAIR_CONFIG_KEY, hashKey); + } + + @Override + @Async("threadPoolTaskExecutor") + public void executeDataRepair(String serialNumber, boolean isShadow, List currentLogs) { + + if (CollectionUtils.isEmpty(currentLogs) || isShadow) { + log.debug("无数据或为影子模式,不执行数据修复: serialNumber={}, isShadow={}", serialNumber, isShadow); + return; + } + + // 方案2优化:一次性批量获取该设备的所有配置,避免重复查询Redis + Set deviceConfigIdentifiers = getDeviceConfigIdentifiers(serialNumber); + if (deviceConfigIdentifiers.isEmpty()) { + log.debug("设备无数据修复配置: serialNumber={}", serialNumber); + return; + } + + + // 查询最近的数据(按时间倒序) + DeviceLog queryParam = new DeviceLog(); + queryParam.setSerialNumber(serialNumber); + queryParam.setIdentityList(new ArrayList<>(deviceConfigIdentifiers)); + queryParam.setBeginTime(DateUtils.getYesterdayDateTime()); + queryParam.setEndTime(DateUtils.getTime()); + + List recentLogs = logService.getDataRepairList(queryParam); + + if (recentLogs == null || recentLogs.size() < 3) { + log.debug("数据为空或数据不足3条,不执行修复: serialNumber={}", serialNumber); + return; + } + Map> identifierLogs = recentLogs.stream().collect(Collectors.groupingBy(DeviceLog::getIdentity)); + for (Map.Entry> entry : identifierLogs.entrySet()) { + String identifier = entry.getKey(); + List value = entry.getValue(); + try { + if (value == null || value.size() < 3) { + log.debug("数据不足3条,跳过修复: serialNumber={}, identifier={}", serialNumber, identifier); + return; + } + + // 取最近3条数据(已经是按时间倒序) + List lastThree = value.stream() + .limit(3) + .collect(Collectors.toList()); + + // 按时间正序排列:A(最早), B(中间), C(最新) + // 因为查询结果是倒序的,所以需要反转 + DeviceLog logC = lastThree.get(0); // 最新的 + DeviceLog logB = lastThree.get(1); // 中间的 + DeviceLog logA = lastThree.get(2); // 最早的 + + // 解析数值 + double valueA = parseDouble(logA.getLogValue()); + double valueB = parseDouble(logB.getLogValue()); + double valueC = parseDouble(logC.getLogValue()); + + if (Double.isNaN(valueA) || Double.isNaN(valueB) || Double.isNaN(valueC)) { + log.debug("数据值无效,跳过修复: serialNumber={}, identifier={}", serialNumber, identifier); + return; + } + + // 计算平均值 + double avg = (valueA + valueC) / 2.0; + + // 检查是否需要修复:B与(A+C)/2的差值超过30% + double diff = Math.abs(valueB - avg); + double threshold = Math.abs(avg) * REPAIR_THRESHOLD; + + if (diff > threshold) { + // 需要修复,更新中间的数据点B + String newValue = String.format("%.3f", avg); + log.info("检测到异常数据,自动修复: serialNumber={}, identifier={}, 原值={}, 修复值={}", serialNumber, identifier, logB.getLogValue(), newValue); + + DeviceLog updateLog = new DeviceLog(); + updateLog.setLogId(logB.getLogId()); + updateLog.setLogValue(newValue); + int result = deviceLogService.updateDeviceLog(updateLog); + if (result > 0) { + log.info("数据修复成功: serialNumber={}, identifier={}, logId={}, 修复值={}", serialNumber, + identifier, logB.getLogId(), newValue); + } else { + log.warn("数据修复失败: serialNumber={}, identifier={}, logId={}", serialNumber, identifier, + logB.getLogId()); + } } else { + log.debug("数据正常,无需修复: serialNumber={}, identifier={}, diff={}, threshold={}", serialNumber, identifier, diff, threshold); + } + + } catch (Exception e) { + log.error("数据修复执行异常: serialNumber={}, identifier={}", serialNumber, identifier, e); + } + } + } + + /** + * 解析字符串为double值 + */ + private double parseDouble(String value) { + if (value == null || value.trim().isEmpty()) { + return Double.NaN; + } + try { + return Double.parseDouble(value.trim()); + } catch (NumberFormatException e) { + return Double.NaN; + } + } + + /** + * 构建设备物模型的hashKey + * 格式:serialNumber:identifier + */ + private String buildDeviceIdentifierKey(String serialNumber, String identifier) { + return serialNumber + ":" + identifier; + } + + /** + * 获取设备的所有配置标识符(用于executeDataRepair优化) + * 一次性批量获取该设备的所有配置,避免重复查询Redis + */ + private Set getDeviceConfigIdentifiers(String serialNumber) { + Set identifiers = new HashSet<>(); + try { + // 获取所有hashKey + Set hashKeys = redisTemplate.opsForHash().keys(FastBeeConstant.REDIS.DATA_REPAIR_CONFIG_KEY); + if (hashKeys != null && !hashKeys.isEmpty()) { + String prefix = serialNumber + ":"; + for (Object hashKeyObj : hashKeys) { + String hashKey = hashKeyObj.toString(); + // 过滤出该设备的配置 + if (hashKey.startsWith(prefix)) { + // 提取identifier(去掉设备前缀) + String identifier = hashKey.substring(prefix.length()); + identifiers.add(identifier); + } + } + } + } catch (Exception e) { + log.warn("获取设备配置标识符失败: serialNumber={}", serialNumber, e); + } + return identifiers; + } +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DeviceLogServiceImpl.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DeviceLogServiceImpl.java index 67bf6924..f61aa238 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DeviceLogServiceImpl.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DeviceLogServiceImpl.java @@ -2,19 +2,17 @@ package com.fastbee.iot.service.impl; import com.alibaba.fastjson2.JSONObject; import com.fastbee.common.utils.DateUtils; +import com.fastbee.common.utils.SecurityUtils; import com.fastbee.common.utils.StringUtils; import com.fastbee.iot.domain.Device; import com.fastbee.iot.domain.DeviceLog; import com.fastbee.iot.domain.ThingsModel; -import com.fastbee.iot.model.DeviceReport; -import com.fastbee.iot.model.HistoryModel; +import com.fastbee.iot.model.*; import com.fastbee.iot.service.IDeviceService; import com.fastbee.iot.service.IThingsModelService; -import com.fastbee.iot.model.ThingsModelLogCountVO; import com.fastbee.iot.model.param.DataCenterParam; import com.fastbee.iot.tdengine.service.ILogService; import com.fastbee.iot.mapper.DeviceLogMapper; -import com.fastbee.iot.model.MonitorModel; import com.fastbee.iot.service.IDeviceLogService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -88,7 +86,17 @@ public class DeviceLogServiceImpl implements IDeviceLogService { */ @Override public int insertDeviceLog(DeviceLog deviceLog) { - deviceLog.setCreateTime(DateUtils.getNowDate()); + if (deviceLog.getCreateTime() == null) { + deviceLog.setCreateTime(DateUtils.getNowDate()); + } else { + log.info("dateRepairInsertDeviceLog:{}", deviceLog.getSerialNumber()); + Long userId = SecurityUtils.getUserId(); + String username = SecurityUtils.getUsername(); + deviceLog.setUserId(userId); + deviceLog.setUserName(username); + deviceLog.setTenantId(userId); + deviceLog.setTenantName(username); + } return logService.saveDeviceLog(deviceLog); } diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DeviceServiceImpl.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DeviceServiceImpl.java index 9faeeaf8..09be416b 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DeviceServiceImpl.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DeviceServiceImpl.java @@ -125,9 +125,10 @@ public class DeviceServiceImpl implements IDeviceService { private ISipRelationService sipRelationService; @Resource private IThingsModelService thingsModelService; - + @Resource - private ApplicationContext applicationContext; + @Lazy + private IDataRepairService dataRepairService; @Resource private EventLogMapper eventLogMapper; @@ -713,6 +714,9 @@ public class DeviceServiceImpl implements IDeviceService { } /* ★★★★★★★★★★★★★★★★★★★★★★ 存储数据 - 结束 ★★★★★★★★★★★★★★★★★★★★★★ */ + // 数据修复:在存储数据完成后,异步执行数据修复 + dataRepairService.executeDataRepair(serialNumber, isShadow, deviceLogList); + return list; } diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/ThingsModelServiceImpl.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/ThingsModelServiceImpl.java index 12b1b467..9ae8bb87 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/ThingsModelServiceImpl.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/ThingsModelServiceImpl.java @@ -782,22 +782,4 @@ public class ThingsModelServiceImpl implements IThingsModelService { return thingsModel; } - /** - * 判断是否为纯计算物模型 - * 如果公式包含{},则认为是纯计算物模型(依赖其他物模型计算值) - * - * @param formula 计算公式 - * @return 0=设备上报(默认),1=纯计算,2=其他(预留) - */ - private Integer determineIsCalculated(String formula) { - if (StringUtils.isEmpty(formula)) { - return 0; // 默认设备上报 - } - // 如果公式包含{},则认为是纯计算物模型 - if (formula.contains("{") && formula.contains("}")) { - return 1; // 纯计算 - } - return 0; // 设备上报 - } - } diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/ILogService.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/ILogService.java index 99d4b9b2..ca8dd096 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/ILogService.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/ILogService.java @@ -52,6 +52,8 @@ public interface ILogService { **/ List selectDeviceLogList(DeviceLog deviceLog); + List getDataRepairList(DeviceLog deviceLog); + /** * 查询监测数据列表 **/ diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/impl/MySqlLogServiceImpl.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/impl/MySqlLogServiceImpl.java index dac10214..f5918c07 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/impl/MySqlLogServiceImpl.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/impl/MySqlLogServiceImpl.java @@ -19,6 +19,7 @@ import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -99,6 +100,11 @@ public class MySqlLogServiceImpl implements ILogService { return deviceLogMapper.selectDeviceLogList(deviceLog); } + @Override + public List getDataRepairList(DeviceLog deviceLog) { + return deviceLogMapper.getDataRepairList(deviceLog); + } + /*** * 监测数据列表 * @return diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/impl/TdengineLogServiceImpl.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/impl/TdengineLogServiceImpl.java index 3263f8d2..7c7ac7d5 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/impl/TdengineLogServiceImpl.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/impl/TdengineLogServiceImpl.java @@ -144,6 +144,11 @@ public class TdengineLogServiceImpl implements ILogService { return tDDeviceLogMapper.selectDeviceLogList(dbName, deviceLog); } + @Override + public List getDataRepairList(DeviceLog deviceLog) { + return tDDeviceLogMapper.getDataRepairList(dbName, deviceLog); + } + /*** * 监测数据列表 * @return diff --git a/fastbee-service/fastbee-iot-service/src/main/resources/mapper/iot/DeviceLogMapper.xml b/fastbee-service/fastbee-iot-service/src/main/resources/mapper/iot/DeviceLogMapper.xml index f5877e6b..6abd0d77 100644 --- a/fastbee-service/fastbee-iot-service/src/main/resources/mapper/iot/DeviceLogMapper.xml +++ b/fastbee-service/fastbee-iot-service/src/main/resources/mapper/iot/DeviceLogMapper.xml @@ -64,6 +64,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" order by create_time desc + + + +