From e46bfa3ff94a8a1b4daf37c7fcb79c2fab22a72c Mon Sep 17 00:00:00 2001
From: doum <doum>
Date: 星期五, 29 五月 2026 17:10:00 +0800
Subject: [PATCH] 新增智能电表、空调管理

---
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwWorkDeskEnergyServiceImpl.java |  104 ++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 77 insertions(+), 27 deletions(-)

diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwWorkDeskEnergyServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwWorkDeskEnergyServiceImpl.java
index aa2d11c..5d7812b 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwWorkDeskEnergyServiceImpl.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwWorkDeskEnergyServiceImpl.java
@@ -1,7 +1,10 @@
 package com.doumee.service.business.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.exception.BusinessException;
 import com.doumee.core.utils.Constants;
+import com.doumee.core.utils.DateUtil;
 import com.doumee.dao.business.YwConditionerUsageMapper;
 import com.doumee.dao.business.YwElectricalDataMapper;
 import com.doumee.dao.business.model.YwConditionerUsage;
@@ -18,6 +21,7 @@
 import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
@@ -42,13 +46,54 @@
     public List<DailyEnergyStatVO> electricalDailyStats() {
         LocalDate end = LocalDate.now();
         LocalDate start = end.minusDays(DAYS - 1L);
-        LocalDate queryStart = start.minusDays(1L);
+        return buildElectricalDailyStats(start, end);
+    }
+
+    @Override
+    public String refreshElectricalDailyStatsForRange(String readTimeBegin, String readTimeEnd) {
+        if (StringUtils.isBlank(readTimeBegin) || StringUtils.isBlank(readTimeEnd)) {
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "鎶勮〃鏃堕棿娈典笉鑳戒负绌�");
+        }
+        LocalDate start = parseDateTime(readTimeBegin.trim()).minusDays(1);
+        LocalDate end = parseDateTime(readTimeEnd.trim()).plusDays(1);
+        if (start.isAfter(end)) {
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "鎶勮〃鏃堕棿娈垫棤鏁�");
+        }
+        buildElectricalDailyStats(start, end);
+        return "宸插埛鏂版瘡鏃ョ數閲�/鐢佃垂缁熻锛�" + start.format(DATE_FMT) + " ~ " + end.format(DATE_FMT) + "锛�";
+    }
+
+    @Override
+    public List<DailyEnergyStatVO> conditionerDailyStats() {
+        LocalDate end = LocalDate.now();
+        LocalDate start = end.minusDays(DAYS - 1L);
         Map<String, DailyEnergyStatVO> bucket = initDailyBucket(start, end);
 
-        List<YwElectricalData> rows = ywElectricalDataMapper.selectList(new QueryWrapper<YwElectricalData>().lambda()
-                .eq(YwElectricalData::getIsdeleted, Constants.ZERO)
-                .ge(YwElectricalData::getCreateDate, java.sql.Date.valueOf(queryStart))
-                .le(YwElectricalData::getCreateDate, java.sql.Date.valueOf(end.plusDays(1))));
+        List<YwConditionerUsage> rows = ywConditionerUsageMapper.selectList(new QueryWrapper<YwConditionerUsage>().lambda()
+                .eq(YwConditionerUsage::getIsdeleted, Constants.ZERO)
+                .ge(YwConditionerUsage::getUsageDate, java.sql.Date.valueOf(start))
+                .le(YwConditionerUsage::getUsageDate, java.sql.Date.valueOf(end)));
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        for (YwConditionerUsage row : rows) {
+            if (row.getUsageDate() == null) {
+                continue;
+            }
+            String dayKey = sdf.format(row.getUsageDate());
+            if (!bucket.containsKey(dayKey)) {
+                continue;
+            }
+            DailyEnergyStatVO stat = bucket.get(dayKey);
+            stat.setTotalKwh(stat.getTotalKwh().add(nullToZero(row.getSumDl())));
+            stat.setTotalFee(stat.getTotalFee().add(nullToZero(row.getSumDf())));
+        }
+        return normalizeBucket(bucket);
+    }
+
+    private List<DailyEnergyStatVO> buildElectricalDailyStats(LocalDate start, LocalDate end) {
+        LocalDate queryStart = start.minusDays(1L);
+        Map<String, DailyEnergyStatVO> bucket = initDailyBucket(start, end);
+        List<YwElectricalData> rows = loadElectricalRowsForStats(queryStart, end);
 
         SimpleDateFormat dayFmt = new SimpleDateFormat("yyyy-MM-dd");
         SimpleDateFormat readTimeFmt = new SimpleDateFormat(READ_TIME_PATTERN);
@@ -93,31 +138,36 @@
         return normalizeBucket(bucket);
     }
 
-    @Override
-    public List<DailyEnergyStatVO> conditionerDailyStats() {
-        LocalDate end = LocalDate.now();
-        LocalDate start = end.minusDays(DAYS - 1L);
-        Map<String, DailyEnergyStatVO> bucket = initDailyBucket(start, end);
+    private List<YwElectricalData> loadElectricalRowsForStats(LocalDate queryStart, LocalDate end) {
+        String queryStartStr = queryStart.format(DATE_FMT) + " 00:00:00";
+        String queryEndStr = end.format(DATE_FMT) + " 23:59:59";
+        return ywElectricalDataMapper.selectList(new QueryWrapper<YwElectricalData>().lambda()
+                .eq(YwElectricalData::getIsdeleted, Constants.ZERO)
+                .and(w -> w.and(w1 -> w1.isNotNull(YwElectricalData::getAddTime)
+                                .ne(YwElectricalData::getAddTime, "")
+                                .ge(YwElectricalData::getAddTime, queryStartStr)
+                                .le(YwElectricalData::getAddTime, queryEndStr))
+                        .or(w2 -> w2.and(w3 -> w3.isNull(YwElectricalData::getAddTime)
+                                        .or().eq(YwElectricalData::getAddTime, ""))
+                                .ge(YwElectricalData::getCreateDate, java.sql.Date.valueOf(queryStart))
+                                .le(YwElectricalData::getCreateDate, java.sql.Date.valueOf(end.plusDays(1))))));
+    }
 
-        List<YwConditionerUsage> rows = ywConditionerUsageMapper.selectList(new QueryWrapper<YwConditionerUsage>().lambda()
-                .eq(YwConditionerUsage::getIsdeleted, Constants.ZERO)
-                .ge(YwConditionerUsage::getUsageDate, java.sql.Date.valueOf(start))
-                .le(YwConditionerUsage::getUsageDate, java.sql.Date.valueOf(end)));
-
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
-        for (YwConditionerUsage row : rows) {
-            if (row.getUsageDate() == null) {
-                continue;
+    private static LocalDate parseDateTime(String text) {
+        if (text.length() >= 10) {
+            try {
+                return LocalDate.parse(text.substring(0, 10), DATE_FMT);
+            } catch (DateTimeParseException ignored) {
             }
-            String dayKey = sdf.format(row.getUsageDate());
-            if (!bucket.containsKey(dayKey)) {
-                continue;
-            }
-            DailyEnergyStatVO stat = bucket.get(dayKey);
-            stat.setTotalKwh(stat.getTotalKwh().add(nullToZero(row.getSumDl())));
-            stat.setTotalFee(stat.getTotalFee().add(nullToZero(row.getSumDf())));
         }
-        return normalizeBucket(bucket);
+        try {
+            Date date = DateUtil.StringToDate(text, READ_TIME_PATTERN);
+            if (date != null) {
+                return date.toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate();
+            }
+        } catch (Exception ignored) {
+        }
+        throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "鎶勮〃鏃堕棿鏍煎紡涓嶆纭�");
     }
 
     private static void upsertLatestReading(Map<String, Map<String, MeterDayReading>> meterDayLatest,

--
Gitblit v1.9.3