From 0054933e653da5a626fdddd646ed6e4efd4f9a21 Mon Sep 17 00:00:00 2001 From: "review512jwy@163.com" <“review512jwy@163.com”> Date: Sun, 11 Jan 2026 11:23:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=87=E7=94=A8S=E8=AE=BE=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../back/service/common/CommonOpt.java | 25 ++++++--- .../impl/DeviceDataAccumulateServiceImpl.java | 41 +++++++++++--- .../impl/DeviceDataBaStatusServiceImpl.java | 35 +++++++++++- .../impl/DeviceDataMeasureServiceImpl.java | 54 ++++++++++++++++--- 4 files changed, 132 insertions(+), 23 deletions(-) diff --git a/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/common/CommonOpt.java b/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/common/CommonOpt.java index e4e59ce..380b351 100644 --- a/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/common/CommonOpt.java +++ b/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/common/CommonOpt.java @@ -48,10 +48,11 @@ public class CommonOpt { LAST } - private static final String SUFFIX_85 = "_85"; - private static final String SUFFIX_85_9003 = "_85_9003"; - private static final String SUFFIX_111 = "_111"; - private static final String SUFFIX_111_9003 = "_111_9003"; + public static final String SUFFIX_85 = "_85"; + public static final String SUFFIX_85_9003 = "_85_9003"; + public static final String SUFFIX_111 = "_111"; + public static final String SUFFIX_111_9003 = "_111_9003"; + public static final String SUFFIX_S = "_S"; @Value("${spring.datasource.url}") private String dbUrl; @@ -521,13 +522,23 @@ public class CommonOpt { } - public Map queryDeviceInfoMap(List deviceIdList111) { - if (CollectionUtils.isEmpty(deviceIdList111)) { + public Map buildDeviceId85ToSMap(List deviceIds) { + return deviceIds.stream() + .filter(id -> id.endsWith(SUFFIX_85) || id.endsWith(SUFFIX_85_9003)) + .collect(Collectors.toMap( + String::toLowerCase, + id -> (id + SUFFIX_S).toLowerCase(), + (a, b) -> b + )); + } + + public Map queryDeviceInfoMap(List deviceIdList) { + if (CollectionUtils.isEmpty(deviceIdList)) { return Collections.emptyMap(); } DeviceInfoExample example = new DeviceInfoExample(); - example.createCriteria().andDeviceIdIn(deviceIdList111).andFlagEqualTo(0); + example.createCriteria().andDeviceIdIn(deviceIdList).andFlagEqualTo(0); return deviceInfoMapperExt .selectByExampleWithBLOBs(example) diff --git a/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/impl/DeviceDataAccumulateServiceImpl.java b/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/impl/DeviceDataAccumulateServiceImpl.java index c537cc4..4c2fe81 100644 --- a/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/impl/DeviceDataAccumulateServiceImpl.java +++ b/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/impl/DeviceDataAccumulateServiceImpl.java @@ -19,9 +19,7 @@ import com.dongjian.dashboard.back.dao.ex.DeviceRawdataRealtimeMapperExt; import com.dongjian.dashboard.back.dao.ex.FavoritedDeviceMapperExt; import com.dongjian.dashboard.back.dto.data.AccumulateDataSearchParam; import com.dongjian.dashboard.back.dto.device.LineDataSearchParams; -import com.dongjian.dashboard.back.model.DeviceInfo; import com.dongjian.dashboard.back.model.DeviceRawdataRealtime; -import com.dongjian.dashboard.back.model.DeviceRawdataRealtimeExample; import com.dongjian.dashboard.back.service.DeviceDataAccumulateService; import com.dongjian.dashboard.back.service.common.CommonOpt; import com.dongjian.dashboard.back.util.CommonUtil; @@ -29,7 +27,6 @@ import com.dongjian.dashboard.back.util.DateUtil; import com.dongjian.dashboard.back.vo.data.DeviceAccumulateData; import com.dongjian.dashboard.back.vo.device.DeviceIncrement; import com.dongjian.dashboard.back.vo.device.LineData; -import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.pagehelper.PageHelper; import org.apache.commons.collections.CollectionUtils; @@ -113,6 +110,31 @@ public class DeviceDataAccumulateServiceImpl implements DeviceDataAccumulateServ Map realtime111Map = commonOpt.queryRealtimeMap(deviceIdList_111); // Map deviceInfo111Map = commonOpt.queryDeviceInfoMap(deviceIdList_111); + // 查询S备用设备的数据,因为先看备用S设备,有S的话优先用这个 + Map deviceId85ToSMap = commonOpt.buildDeviceId85ToSMap(deviceIds); + List deviceIdList_S = deviceId85ToSMap.values() + .stream() + .toList(); + Map realtimeSMap = commonOpt.queryRealtimeMap(deviceIdList_S); + + // 筛选出S后缀里数据更新的设备,用于查今天的积算值 + List todayDeviceIds = new ArrayList<>(deviceIds); + for (DeviceAccumulateData data : resultList) { + String rawDeviceId = data.getDeviceId(); + String sDeviceId = deviceId85ToSMap.get(rawDeviceId.toLowerCase()); + + DeviceRawdataRealtime sRealtime = realtimeSMap.get(sDeviceId); + if (sRealtime == null || sRealtime.getReceiveTs() == null) { + continue; + } + //sRealtime存在且有receive_ts时 + Long uploadTs = data.getUploadTimestamp(); + if (uploadTs == null || sRealtime.getReceiveTs() > uploadTs) { + todayDeviceIds.remove(rawDeviceId); + todayDeviceIds.add(sDeviceId); + } + } + LocalDateTime now = LocalDateTime.now(ZoneId.of("Asia/Tokyo")); LocalDate today = now.toLocalDate(); LocalDate yesterday = today.minusDays(1); @@ -121,7 +143,7 @@ public class DeviceDataAccumulateServiceImpl implements DeviceDataAccumulateServ int targetSeconds = now.toLocalTime().toSecondOfDay(); // 批量查询增量数据并构建 Map - Map todayMap = dashboardRecordAccumulateMapperExt.selectTodayIncrement(deviceIds, today.getYear(), today.getMonthValue(), today.getDayOfMonth()) + Map todayMap = dashboardRecordAccumulateMapperExt.selectTodayIncrement(todayDeviceIds, today.getYear(), today.getMonthValue(), today.getDayOfMonth()) .stream().collect(Collectors.toMap(di -> di.getDeviceId().toLowerCase(), Function.identity())); Map yesterdayMap = dashboardRecordAccumulateMapperExt.selectYesterdayIncrement(deviceIds, yesterday.getYear(), yesterday.getMonthValue(), yesterday.getDayOfMonth(), targetSeconds) .stream().collect(Collectors.toMap(di -> di.getDeviceId().toLowerCase(), Function.identity())); @@ -130,9 +152,14 @@ public class DeviceDataAccumulateServiceImpl implements DeviceDataAccumulateServ resultList.forEach(data -> { String deviceId = data.getDeviceId().toLowerCase(); - - // 填充今天/昨天/去年值 - data.setCumulativeValue(CommonUtil.formatDecimal(getIncrement(todayMap.get(deviceId), DeviceIncrement::getTodayIncrement), data.getDashboardDecimalPlaces())); + String sDeviceId = deviceId85ToSMap.get(deviceId); + + //*** 填充今天/昨天/去年值 **// + // 今天值,要先看备用S设备,有S的话优先用这个 + data.setCumulativeValue(CommonUtil.formatDecimal( + getIncrement(todayDeviceIds.contains(sDeviceId) ? todayMap.get(sDeviceId) : todayMap.get(deviceId), DeviceIncrement::getTodayIncrement), + data.getDashboardDecimalPlaces()) + ); data.setYesterdayValue(CommonUtil.formatDecimal(getIncrement(yesterdayMap.get(deviceId), DeviceIncrement::getYesterdayIncrement), data.getDashboardDecimalPlaces())); data.setLastYearValue(CommonUtil.formatDecimal(getIncrement(lastYearMap.get(deviceId), DeviceIncrement::getLastYearIncrement), data.getDashboardDecimalPlaces())); diff --git a/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/impl/DeviceDataBaStatusServiceImpl.java b/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/impl/DeviceDataBaStatusServiceImpl.java index d71764c..ce04292 100644 --- a/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/impl/DeviceDataBaStatusServiceImpl.java +++ b/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/impl/DeviceDataBaStatusServiceImpl.java @@ -9,12 +9,14 @@ import com.dongjian.dashboard.back.dao.ex.FavoritedDeviceMapperExt; import com.dongjian.dashboard.back.dto.data.BaStatusDataSearchParam; import com.dongjian.dashboard.back.easyexcel.SecondsToHMSConverter; import com.dongjian.dashboard.back.model.DeviceInfo; +import com.dongjian.dashboard.back.model.DeviceInfoExample; import com.dongjian.dashboard.back.model.DeviceRawdataRealtime; import com.dongjian.dashboard.back.model.DeviceRawdataRealtimeExample; import com.dongjian.dashboard.back.service.DeviceDataBaStatusService; import com.dongjian.dashboard.back.service.common.CommonOpt; import com.dongjian.dashboard.back.vo.data.DeviceAccumulateData; import com.dongjian.dashboard.back.vo.data.DeviceBaStatusData; +import com.dongjian.dashboard.back.vo.data.DeviceMeasureData; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.pagehelper.PageHelper; @@ -106,17 +108,48 @@ public class DeviceDataBaStatusServiceImpl implements DeviceDataBaStatusService Map realtime85Map = commonOpt.queryRealtimeMap(deviceIds); // Map deviceInfo111Map = commonOpt.queryDeviceInfoMap(deviceIdList_111); + // 查询S备用设备的数据 + Map deviceId85ToSMap = commonOpt.buildDeviceId85ToSMap(deviceIds); + List deviceIdList_S = deviceId85ToSMap.values() + .stream() + .toList(); + Map realtimeSMap = commonOpt.queryRealtimeMap(deviceIdList_S); + // 筛选出S后缀里,数据更新的设备,用于查状态 + List sNewerDeviceIds = new ArrayList<>(); + for (DeviceBaStatusData data : resultList) { + String rawDeviceId = data.getDeviceId(); + String sDeviceId = deviceId85ToSMap.get(rawDeviceId.toLowerCase()); + + DeviceRawdataRealtime sRealtime = realtimeSMap.get(sDeviceId); + if (sRealtime == null || sRealtime.getReceiveTs() == null) { + continue; + } + //sRealtime存在且有receive_ts时 + Long uploadTs = data.getUploadTimestamp(); + if (uploadTs == null || sRealtime.getReceiveTs() > uploadTs) { + sNewerDeviceIds.add(sDeviceId); + } + } + //找出s的数据映射 + Map sDeviceInfo = commonOpt.queryDeviceInfoMap(sNewerDeviceIds); + // 查询 favorited_device 表中所有设备的 device_id List favoritedDeviceIds = favoritedDeviceMapperExt.getFavoritedDeviceIds(); for (DeviceBaStatusData data : resultList){ String deviceId = data.getDeviceId().toLowerCase(); + String sDeviceId = deviceId85ToSMap.get(deviceId); data.setContinuousRunningTimeStr(SecondsToHMSConverter.covertSeconds(data.getContinuousRunningTime())); //处理111状态映射 // data.setStatus111(commonOpt.buildStatus111(deviceId, deviceId85To111Map, deviceInfo111Map, realtime111Map, objectMapper)); data.setStatus111(commonOpt.buildRawFirstValue(deviceId, deviceId85To111Map, realtime111Map, objectMapper)); - data.setRunningStatus(commonOpt.mapLastValue(objectMapper, data.getDataMapping(), realtime85Map.get(deviceId))); + + if(sNewerDeviceIds.contains(sDeviceId)) { + data.setRunningStatus(commonOpt.mapLastValue(objectMapper, sDeviceInfo.get(sDeviceId).getDataMapping(), realtimeSMap.get(sDeviceId))); + } else { + data.setRunningStatus(commonOpt.mapLastValue(objectMapper, data.getDataMapping(), realtime85Map.get(deviceId))); + } // 判断设备是否在 favorited_device 表中 data.setCollected(favoritedDeviceIds.contains(deviceId) ? 1 : 0); diff --git a/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/impl/DeviceDataMeasureServiceImpl.java b/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/impl/DeviceDataMeasureServiceImpl.java index 06596b6..fe304cc 100644 --- a/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/impl/DeviceDataMeasureServiceImpl.java +++ b/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/impl/DeviceDataMeasureServiceImpl.java @@ -19,6 +19,7 @@ import com.dongjian.dashboard.back.service.DeviceDataMeasureService; import com.dongjian.dashboard.back.service.common.CommonOpt; import com.dongjian.dashboard.back.service.common.LineDataHourAggregator; import com.dongjian.dashboard.back.util.CommonUtil; +import com.dongjian.dashboard.back.vo.data.DeviceAccumulateData; import com.dongjian.dashboard.back.vo.data.DeviceMeasureData; import com.dongjian.dashboard.back.vo.device.LineData; import com.fasterxml.jackson.databind.JsonNode; @@ -64,6 +65,12 @@ public class DeviceDataMeasureServiceImpl implements DeviceDataMeasureService { private CommonOpt commonOpt; + private static final Comparator TEMP_HUMIDITY_COMPARATOR = + Comparator.comparingInt(m -> { + if (DeviceAttrCode.MEASURE_TEMPERATURE.equals(m.getAttrCode())) return 0; + if (DeviceAttrCode.MEASURE_HUMIDITY.equals(m.getAttrCode())) return 1; + return 99; + }); @Override @@ -118,6 +125,29 @@ public class DeviceDataMeasureServiceImpl implements DeviceDataMeasureService { Map realtime111Map = commonOpt.queryRealtimeMap(deviceIdList_111); // Map deviceInfo111Map = commonOpt.queryDeviceInfoMap(deviceIdList_111); + // 查询S备用设备的数据 + Map deviceId85ToSMap = commonOpt.buildDeviceId85ToSMap(deviceIds); + List deviceIdList_S = deviceId85ToSMap.values() + .stream() + .toList(); + Map realtimeSMap = commonOpt.queryRealtimeMap(deviceIdList_S); + // 筛选出S后缀里,数据更新的设备,用于查测量值 + List searchDeviceIds = new ArrayList<>(deviceIds); + for (DeviceMeasureData data : resultList) { + String rawDeviceId = data.getDeviceId(); + String sDeviceId = deviceId85ToSMap.get(rawDeviceId.toLowerCase()); + + DeviceRawdataRealtime sRealtime = realtimeSMap.get(sDeviceId); + if (sRealtime == null || sRealtime.getReceiveTs() == null) { + continue; + } + //sRealtime存在且有receive_ts时 + Long uploadTs = data.getUploadTimestamp(); + if (uploadTs == null || sRealtime.getReceiveTs() > uploadTs) { + searchDeviceIds.add(sDeviceId); + } + } + ZoneId tokyoZone = ZoneId.of("Asia/Tokyo"); LocalDate tokyoToday = LocalDate.now(tokyoZone); int year = tokyoToday.getYear(); @@ -126,7 +156,7 @@ public class DeviceDataMeasureServiceImpl implements DeviceDataMeasureService { // 查询 dashboard_realtime_measure 数据 List realtimeList = - dashboardRealtimeMeasureMapperExt.selectRealtimeMeasureByDevices(deviceIds); + dashboardRealtimeMeasureMapperExt.selectRealtimeMeasureByDevices(searchDeviceIds); Map> realtimeMap = realtimeList.stream() .collect(Collectors.groupingBy(m -> m.getDeviceId().toLowerCase())); @@ -138,22 +168,30 @@ public class DeviceDataMeasureServiceImpl implements DeviceDataMeasureService { // 如果在实时表中存在记录,则更新 measurementValue/max/min List realtime = realtimeMap.get(deviceId); + List realtimeS = realtimeMap.get(deviceId85ToSMap.get(deviceId));// 20260109需求,对测量值,要先看备用S设备,有S的话优先用这个 if (CollectionUtils.isNotEmpty(realtime)) { - List sortedRealtime = realtime;// 默认值为原始数据 + List sortedRealtime = realtime; + List sortedRealtimeS = realtimeS; if (Constants.DEVICE_TYPE_TEMPERATURE_HUMIDITY.contains(data.getCategoryId())){ // 根据 attrCode 排序,temperature 排在前,humidity 排在后 sortedRealtime = realtime.stream() - .sorted(Comparator.comparingInt(m -> { - if (DeviceAttrCode.MEASURE_TEMPERATURE.equals(m.getAttrCode())) return 0; - if (DeviceAttrCode.MEASURE_HUMIDITY.equals(m.getAttrCode())) return 1; - return 99; - })) + .sorted(TEMP_HUMIDITY_COMPARATOR) .toList(); + if (realtimeS != null) { + sortedRealtimeS = realtimeS.stream() + .sorted(TEMP_HUMIDITY_COMPARATOR) + .toList(); + } } // 获取所有 MeasurementValue 并用逗号连接(不需要日期过滤) - String measurementValues = sortedRealtime.stream() + // 20260109需求,对测量值,要先看备用S设备,有S的话优先用这个,最大值最小值不需要 + List source = + (sortedRealtimeS != null && !sortedRealtimeS.isEmpty()) + ? sortedRealtimeS + : sortedRealtime; + String measurementValues = source.stream() .map(DashboardRealtimeMeasure::getUploadValue) // 提取每个 UploadValue .filter(StringUtils::isNotBlank) // 过滤空值 .collect(Collectors.joining(","));