From 945b85c3ce4d09ace8993cbf31fdb34b6b927244 Mon Sep 17 00:00:00 2001
From: DYL <Dn1332079466>
Date: 星期六, 08 二月 2025 15:49:34 +0800
Subject: [PATCH] 同环比分析

---
 zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/IStatisticalAnalysisService.java         |   36 ++
 zhitan-common/src/main/java/com/zhitan/common/constant/TimeTypeConst.java                                   |   25 +
 zhitan-system/src/main/java/com/zhitan/dataitem/mapper/DataItemMapper.java                                  |   12 
 zhitan-system/src/main/java/com/zhitan/dataitem/service/impl/DataItemServiceImpl.java                       |   14 +
 zhitan-admin/src/main/java/com/zhitan/web/controller/statisticalAnalysis/StatisticalAnalysisController.java |  129 +++++++++
 zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisYoYVO.java                 |   42 +++
 zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/impl/StatisticalAnalysisServiceImpl.java |  293 ++++++++++++++++++++++
 zhitan-system/src/main/java/com/zhitan/dataitem/service/IDataItemService.java                               |   11 
 zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisMoMVO.java                 |   42 +++
 zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisMoMExcel.java              |   47 +++
 zhitan-system/src/main/resources/mapper/dataitem/DataItemMapper.xml                                         |   16 +
 zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/dto/DataAnalysisMoMDTO.java               |   48 +++
 zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisYoYExcel.java              |   47 +++
 13 files changed, 762 insertions(+), 0 deletions(-)

diff --git a/zhitan-admin/src/main/java/com/zhitan/web/controller/statisticalAnalysis/StatisticalAnalysisController.java b/zhitan-admin/src/main/java/com/zhitan/web/controller/statisticalAnalysis/StatisticalAnalysisController.java
new file mode 100644
index 0000000..b93f9c7
--- /dev/null
+++ b/zhitan-admin/src/main/java/com/zhitan/web/controller/statisticalAnalysis/StatisticalAnalysisController.java
@@ -0,0 +1,129 @@
+package com.zhitan.web.controller.statisticalAnalysis;
+
+import com.zhitan.common.core.controller.BaseController;
+import com.zhitan.common.core.domain.AjaxResult;
+import com.zhitan.common.utils.poi.ExcelUtil;
+import com.zhitan.statisticalAnalysis.domain.dto.DataAnalysisMoMDTO;
+import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisMoMExcel;
+import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisMoMVO;
+import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisYoYExcel;
+import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisYoYVO;
+import com.zhitan.statisticalAnalysis.service.IStatisticalAnalysisService;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * 缁熻鍒嗘瀽 鎺у埗灞�
+ */
+@RestController
+@RequestMapping("/statisticalAnalysis")
+public class StatisticalAnalysisController extends BaseController {
+
+    @Autowired
+    private IStatisticalAnalysisService analysisService;
+
+
+    @PostMapping("/getElectricDataComparisonYoY")
+    @ApiOperation(value = "鑾峰彇鐢佃兘鑰楀悓姣旀暟鎹�", notes = "鑾峰彇鐢佃兘鑰楀悓姣旀暟鎹�")
+    public AjaxResult listElectricDataComparisonYoY(@RequestBody @Validated DataAnalysisMoMDTO dto) {
+        List<DataAnalysisYoYVO> yoyList = analysisService.listElectricDataComparisonYoY(dto);
+        return AjaxResult.success(yoyList);
+    }
+
+    @PostMapping("/getElectricDataComparisonMoM")
+    @ApiOperation(value = "鑾峰彇鐢佃兘鑰楃幆姣旀暟鎹�", notes = "鑾峰彇鐢佃兘鑰楃幆姣旀暟鎹�")
+    public AjaxResult listElectricDataComparisonMoM(@RequestBody @Validated DataAnalysisMoMDTO dto) {
+        List<DataAnalysisMoMVO> momList = analysisService.listElectricDataComparisonMoM(dto);
+        return AjaxResult.success(momList);
+    }
+
+    @PostMapping("/getWaterDataComparisonYoY")
+    @ApiOperation(value = "鑾峰彇姘磋兘鑰楀悓姣旀暟鎹�", notes = "鑾峰彇姘磋兘鑰楀悓姣旀暟鎹�")
+    public AjaxResult listWaterDataComparisonYoY(@RequestBody @Validated DataAnalysisMoMDTO dto) {
+        List<DataAnalysisYoYVO> yoyList = analysisService.listWaterDataComparisonYoY(dto);
+        return AjaxResult.success(yoyList);
+    }
+
+    @PostMapping("/getWaterDataComparisonMoM")
+    @ApiOperation(value = "鑾峰彇姘磋兘鑰楃幆姣旀暟鎹�", notes = "鑾峰彇姘磋兘鑰楃幆姣旀暟鎹�")
+    public AjaxResult listWaterDataComparisonMoM(@RequestBody @Validated DataAnalysisMoMDTO dto) {
+        List<DataAnalysisMoMVO> momList = analysisService.listWaterDataComparisonMoM(dto);
+        return AjaxResult.success(momList);
+    }
+
+    @PostMapping("/exportElectricYoY")
+    @ApiOperation(value = "瀵煎嚭鐢佃兘鑰楀悓姣旀暟鎹�", notes = "瀵煎嚭鐢佃兘鑰楀悓姣旀暟鎹�")
+    public AjaxResult exportElectricComparisonYoY(@RequestBody @Validated DataAnalysisMoMDTO dto) {
+        List<DataAnalysisYoYExcel> yoYExcelsList = new ArrayList<>();
+        List<DataAnalysisYoYVO> yoYList = analysisService.listElectricDataComparisonYoY(dto);
+        if (CollectionUtils.isNotEmpty(yoYList)) {
+            for (DataAnalysisYoYVO vo : yoYList) {
+                DataAnalysisYoYExcel excel = new DataAnalysisYoYExcel();
+                BeanUtils.copyProperties(vo, excel);
+                yoYExcelsList.add(excel);
+            }
+        }
+        ExcelUtil<DataAnalysisYoYExcel> util = new ExcelUtil<>(DataAnalysisYoYExcel.class);
+        return util.exportExcel(yoYExcelsList, "鐢电患鍚堣兘鑰楀悓姣斾俊鎭�");
+    }
+
+//    @PostMapping("/exportElectricMoM")
+//    @ApiOperation(value = "瀵煎嚭鐢佃兘鑰楃幆姣旀暟鎹�", notes = "瀵煎嚭鐢佃兘鑰楃幆姣旀暟鎹�")
+//    public AjaxResult exportElectricComparisonMoM(@RequestBody @Validated DataAnalysisMoMDTO dto) {
+//        List<DataAnalysisMoMExcel> moMExcelsList = new ArrayList<>();
+//        List<DataAnalysisMoMVO> moMList = analysisService.listElectricDataComparisonMoM(dto);
+//        if (CollectionUtils.isNotEmpty(moMList)) {
+//            for (DataAnalysisMoMVO vo : moMList) {
+//                DataAnalysisMoMExcel excel = new DataAnalysisMoMExcel();
+//                BeanUtils.copyProperties(vo, excel);
+//                moMExcelsList.add(excel);
+//            }
+//        }
+//        ExcelUtil<DataAnalysisMoMExcel> util = new ExcelUtil<>(DataAnalysisMoMExcel.class);
+//        return util.exportRealTimeDataExcel(moMExcelsList, "鐢电患鍚堣兘鑰楃幆姣斾俊鎭�");
+//    }
+
+    @PostMapping("/exportWaterYoY")
+    @ApiOperation(value = "瀵煎嚭姘磋�楀悓姣旀暟鎹�", notes = "瀵煎嚭姘磋�楀悓姣旀暟鎹�")
+    public AjaxResult exportWaterComparisonYoY(@RequestBody @Validated DataAnalysisMoMDTO dto) {
+        List<DataAnalysisYoYExcel> yoYExcelsList = new ArrayList<>();
+        List<DataAnalysisYoYVO> yoYList = analysisService.listWaterDataComparisonYoY(dto);
+        if (CollectionUtils.isNotEmpty(yoYList)) {
+            for (DataAnalysisYoYVO vo : yoYList) {
+                DataAnalysisYoYExcel excel = new DataAnalysisYoYExcel();
+                BeanUtils.copyProperties(vo, excel);
+                yoYExcelsList.add(excel);
+            }
+        }
+        ExcelUtil<DataAnalysisYoYExcel> util = new ExcelUtil<>(DataAnalysisYoYExcel.class);
+        return util.exportExcel(yoYExcelsList, "姘寸患鍚堣兘鑰楄�楀悓姣斾俊鎭�");
+    }
+
+    @PostMapping("/exportWaterMoM")
+    @ApiOperation(value = "瀵煎嚭姘磋�楃幆姣旀暟鎹�", notes = "瀵煎嚭姘磋�楃幆姣旀暟鎹�")
+    public AjaxResult exportWaterComparisonMoM(@RequestBody @Validated DataAnalysisMoMDTO dto) {
+        List<DataAnalysisMoMExcel> moMExcelsList = new ArrayList<>();
+        List<DataAnalysisMoMVO> moMList = analysisService.listWaterDataComparisonMoM(dto);
+        if (CollectionUtils.isNotEmpty(moMList)) {
+            for (DataAnalysisMoMVO vo : moMList) {
+                DataAnalysisMoMExcel excel = new DataAnalysisMoMExcel();
+                BeanUtils.copyProperties(vo, excel);
+                moMExcelsList.add(excel);
+            }
+        }
+        ExcelUtil<DataAnalysisMoMExcel> util = new ExcelUtil<>(DataAnalysisMoMExcel.class);
+        return util.exportExcel(moMExcelsList, "姘寸患鍚堣兘鑰楄�楃幆姣斾俊鎭�");
+    }
+
+}
diff --git a/zhitan-common/src/main/java/com/zhitan/common/constant/TimeTypeConst.java b/zhitan-common/src/main/java/com/zhitan/common/constant/TimeTypeConst.java
new file mode 100644
index 0000000..0847ab2
--- /dev/null
+++ b/zhitan-common/src/main/java/com/zhitan/common/constant/TimeTypeConst.java
@@ -0,0 +1,25 @@
+package com.zhitan.common.constant;
+
+/**
+ * @Description: 鍛ㄦ湡绫诲瀷
+ * @author: yxw
+ * @date: 2022骞�03鏈�17鏃� 12:33
+ */
+public class TimeTypeConst {
+    /**
+     * 鍛ㄦ湡绫诲瀷 - 灏忔椂
+     */
+    public static final String TIME_TYPE_HOUR="HOUR";
+    /**
+     * 鍛ㄦ湡绫诲瀷 - 鏃�
+     */
+    public static final String TIME_TYPE_DAY="DAY";
+    /**
+     * 鍛ㄦ湡绫诲瀷 - 鏈�
+     */
+    public static final String TIME_TYPE_MONTH="MONTH";
+    /**
+     * 鍛ㄦ湡绫诲瀷 - 骞�
+     */
+    public static final String TIME_TYPE_YEAR="YEAR";
+}
diff --git a/zhitan-system/src/main/java/com/zhitan/dataitem/mapper/DataItemMapper.java b/zhitan-system/src/main/java/com/zhitan/dataitem/mapper/DataItemMapper.java
index d33b810..2f6d9ab 100644
--- a/zhitan-system/src/main/java/com/zhitan/dataitem/mapper/DataItemMapper.java
+++ b/zhitan-system/src/main/java/com/zhitan/dataitem/mapper/DataItemMapper.java
@@ -110,4 +110,16 @@
      */
     List<CarbonEmission> getDownCarbonEmission(@Param("beginTime") Date beginTime, @Param("endTime") Date endTime,
                                              @Param("timeType") String timeType, @Param("indexId") String indexId);
+
+    /**
+     * 鏍规嵁indexId涓庢椂闂磋寖鍥存煡璇㈠皬鏃剁殑dataitem淇℃伅
+     *
+     * @param beginTime 寮�濮嬫椂闂�
+     * @param endTime   鎴鏃堕棿
+     * @param timeType  鏃堕棿绫诲瀷
+     * @param indexIds  鐐逛綅闆嗗悎
+     * @return
+     */
+    List<DataItem> getDataItemHourInforByIndexIds(@Param("beginTime") Date beginTime, @Param("endTime") Date endTime,
+                                                  @Param("timeType") String timeType, @Param("indexIds") List<String> indexIds);
 }
diff --git a/zhitan-system/src/main/java/com/zhitan/dataitem/service/IDataItemService.java b/zhitan-system/src/main/java/com/zhitan/dataitem/service/IDataItemService.java
index 6266f72..993beb7 100644
--- a/zhitan-system/src/main/java/com/zhitan/dataitem/service/IDataItemService.java
+++ b/zhitan-system/src/main/java/com/zhitan/dataitem/service/IDataItemService.java
@@ -77,4 +77,15 @@
      * @return
      */
     BigDecimal getDataItemValueByIndexIds(String timeCode, List<String> indexIds);
+
+    /**
+     * 鏍规嵁indexId涓庢椂闂磋寖鍥存煡璇㈠皬鏃剁殑dataitem淇℃伅
+     *
+     * @param beginTime 寮�濮嬫椂闂�
+     * @param endTime   鎴鏃堕棿
+     * @param timeType  鏃堕棿绫诲瀷
+     * @param indexIds  鐐逛綅闆嗗悎
+     * @return
+     */
+    List<DataItem> getDataItemHourInforByIndexIds(Date beginTime, Date endTime, String timeType, List<String> indexIds);
 }
diff --git a/zhitan-system/src/main/java/com/zhitan/dataitem/service/impl/DataItemServiceImpl.java b/zhitan-system/src/main/java/com/zhitan/dataitem/service/impl/DataItemServiceImpl.java
index 0b82a1d..1e29b7f 100644
--- a/zhitan-system/src/main/java/com/zhitan/dataitem/service/impl/DataItemServiceImpl.java
+++ b/zhitan-system/src/main/java/com/zhitan/dataitem/service/impl/DataItemServiceImpl.java
@@ -103,4 +103,18 @@
     public BigDecimal getDataItemValueByIndexIds(String timeCode, List<String> indexIds) {
         return dataItemMapper.getDataItemValueByIndexIds(timeCode, indexIds);
     }
+
+    /**
+     * 鏍规嵁indexId涓庢椂闂磋寖鍥存煡璇㈠皬鏃剁殑dataitem淇℃伅
+     *
+     * @param beginTime 寮�濮嬫椂闂�
+     * @param endTime   鎴鏃堕棿
+     * @param timeType  鏃堕棿绫诲瀷
+     * @param indexIds  鐐逛綅闆嗗悎
+     * @return
+     */
+    @Override
+    public List<DataItem> getDataItemHourInforByIndexIds(Date beginTime, Date endTime, String timeType, List<String> indexIds) {
+        return dataItemMapper.getDataItemHourInforByIndexIds(beginTime, endTime, timeType, indexIds);
+    }
 }
diff --git a/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/dto/DataAnalysisMoMDTO.java b/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/dto/DataAnalysisMoMDTO.java
new file mode 100644
index 0000000..53ea2e2
--- /dev/null
+++ b/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/dto/DataAnalysisMoMDTO.java
@@ -0,0 +1,48 @@
+package com.zhitan.statisticalAnalysis.domain.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.zhitan.common.annotation.Excel;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+/**
+ * 鏁版嵁鍒嗘瀽鐜瘮 璇锋眰鍙傛暟
+ *
+ * @Author: Zhujw
+ * @Date: 2023/3/3
+ */
+@Data
+public class DataAnalysisMoMDTO {
+
+
+    /**
+     * 缁熻寮�濮嬫椂闂�
+     */
+    @NotNull(message = "璇风淮鎶ゆ煡璇㈡椂闂�")
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "鎶ヨ寮�濮嬫椂闂�", dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date beginTime;
+
+    /**
+     * 缁熻寮�濮嬫椂闂�
+     */
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "鎶ヨ寮�濮嬫椂闂�", dateFormat = "yyyy-MM-dd HH:mm:ss")
+    @NotNull(message = "璇风淮鎶ゆ煡璇㈡椂闂�")
+    private Date endTime;
+
+    /**
+     * 鏃堕棿绫诲瀷
+     */
+    @NotBlank(message = "鏈壘鍒版椂闂寸被鍨�")
+    private String timeType;
+
+    /**
+     * 妯″瀷鑺傜偣id
+     */
+    @NotBlank(message = "鏈壘鍒版ā鍨嬭妭鐐逛俊鎭�")
+    private String nodeId;
+}
\ No newline at end of file
diff --git a/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisMoMExcel.java b/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisMoMExcel.java
new file mode 100644
index 0000000..d2212da
--- /dev/null
+++ b/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisMoMExcel.java
@@ -0,0 +1,47 @@
+package com.zhitan.statisticalAnalysis.domain.vo;
+
+import com.zhitan.common.annotation.Excel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 鏁版嵁鍒嗘瀽鐜瘮 瀵煎嚭Excel
+ *
+ * @Author: Zhujw
+ * @Date: 2023/3/3
+ */
+@Data
+public class DataAnalysisMoMExcel {
+
+
+    /**
+     * 鐢ㄨ兘鍗曞厓鍚嶇О
+     */
+    @Excel(name = "鐢ㄨ兘鍗曞厓")
+    private String energyUnitName;
+
+    /**
+     * 鏈湡鍊�
+     */
+    @Excel(name = "鏈湡鍊�")
+    private BigDecimal currentValue;
+
+    /**
+     * 鍚屾湡鍊�
+     */
+    @Excel(name = "鍚屾湡鍊�")
+    private BigDecimal oldValue;
+
+    /**
+     * 鍚屾瘮鍊�
+     */
+    @Excel(name = "鍚屾瘮鍊�")
+    private BigDecimal ratio;
+
+    /**
+     * 鍗曚綅
+     */
+    @Excel(name = "鍗曚綅")
+    private String unit;
+}
diff --git a/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisMoMVO.java b/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisMoMVO.java
new file mode 100644
index 0000000..f675130
--- /dev/null
+++ b/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisMoMVO.java
@@ -0,0 +1,42 @@
+package com.zhitan.statisticalAnalysis.domain.vo;
+
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 鏁版嵁鍒嗘瀽鐜瘮 杩斿洖vo
+ *
+ * @Author: Zhujw
+ * @Date: 2023/3/3
+ */
+@Data
+public class DataAnalysisMoMVO {
+
+
+    /**
+     * 鍗曚綅
+     */
+    private String unit;
+
+    /**
+     * 鐢ㄨ兘鍗曞厓鍚嶇О
+     */
+    private String energyUnitName;
+
+    /**
+     * 鏈湡鍊�
+     */
+    private BigDecimal currentValue;
+
+    /**
+     * 鍚屾湡鍊�
+     */
+    private BigDecimal oldValue;
+
+    /**
+     * 鍚屾瘮鍊�
+     */
+    private BigDecimal ratio;
+}
diff --git a/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisYoYExcel.java b/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisYoYExcel.java
new file mode 100644
index 0000000..e2516e4
--- /dev/null
+++ b/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisYoYExcel.java
@@ -0,0 +1,47 @@
+package com.zhitan.statisticalAnalysis.domain.vo;
+
+import com.zhitan.common.annotation.Excel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 鏁版嵁鍒嗘瀽鍚屾瘮 瀵煎嚭Excel
+ *
+ * @Author: Zhujw
+ * @Date: 2023/3/3
+ */
+@Data
+public class DataAnalysisYoYExcel {
+
+
+    /**
+     * 鐢ㄨ兘鍗曞厓鍚嶇О
+     */
+    @Excel(name = "鐢ㄨ兘鍗曞厓鍚嶇О")
+    private String energyUnitName;
+
+    /**
+     * 鏈湡鍊�
+     */
+    @Excel(name = "鏈湡鍊�")
+    private BigDecimal currentValue;
+
+    /**
+     * 鍚屾湡鍊�
+     */
+    @Excel(name = "鍚屾湡鍊�")
+    private BigDecimal oldValue;
+
+    /**
+     * 鍚屾瘮鍊�
+     */
+    @Excel(name = "鍚屾瘮鍊�")
+    private BigDecimal ratio;
+
+    /**
+     * 鍗曚綅
+     */
+    @Excel(name = "鍗曚綅")
+    private String unit;
+}
diff --git a/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisYoYVO.java b/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisYoYVO.java
new file mode 100644
index 0000000..49e0223
--- /dev/null
+++ b/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisYoYVO.java
@@ -0,0 +1,42 @@
+package com.zhitan.statisticalAnalysis.domain.vo;
+
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 鏁版嵁鍒嗘瀽鍚屾瘮 杩斿洖vo
+ *
+ * @Author: Zhujw
+ * @Date: 2023/3/3
+ */
+@Data
+public class DataAnalysisYoYVO {
+
+
+    /**
+     * 鍗曚綅
+     */
+    private String unit;
+
+    /**
+     * 鐢ㄨ兘鍗曞厓鍚嶇О
+     */
+    private String energyUnitName;
+
+    /**
+     * 鏈湡鍊�
+     */
+    private BigDecimal currentValue;
+
+    /**
+     * 鍚屾湡鍊�
+     */
+    private BigDecimal oldValue;
+
+    /**
+     * 鍚屾瘮鍊�
+     */
+    private BigDecimal ratio;
+}
diff --git a/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/IStatisticalAnalysisService.java b/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/IStatisticalAnalysisService.java
new file mode 100644
index 0000000..4add9e7
--- /dev/null
+++ b/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/IStatisticalAnalysisService.java
@@ -0,0 +1,36 @@
+package com.zhitan.statisticalAnalysis.service;
+
+import com.zhitan.statisticalAnalysis.domain.dto.DataAnalysisMoMDTO;
+import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisMoMVO;
+import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisYoYVO;
+
+import java.util.List;
+
+/**
+ * 缁熻鍒嗘瀽  鎺ュ彛灞�
+ *
+ * @Author: Zhujw
+ * @Date: 2023/3/1
+ */
+public interface IStatisticalAnalysisService {
+
+    /**
+     * 鑾峰彇鐢佃兘鑰楀悓姣旀暟鎹�
+     */
+    List<DataAnalysisYoYVO> listElectricDataComparisonYoY(DataAnalysisMoMDTO dto);
+
+    /**
+     * 鑾峰彇鐢佃兘鑰楃幆姣旀暟鎹�
+     */
+    List<DataAnalysisMoMVO> listElectricDataComparisonMoM(DataAnalysisMoMDTO dto);
+
+    /**
+     * 鑾峰彇鑳借�楀悓姣旀暟鎹�
+     */
+    List<DataAnalysisYoYVO> listWaterDataComparisonYoY(DataAnalysisMoMDTO dto);
+
+    /**
+     * 鑾峰彇鑳借�楃幆姣旀暟鎹�
+     */
+    List<DataAnalysisMoMVO> listWaterDataComparisonMoM(DataAnalysisMoMDTO dto);
+}
\ No newline at end of file
diff --git a/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/impl/StatisticalAnalysisServiceImpl.java b/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/impl/StatisticalAnalysisServiceImpl.java
new file mode 100644
index 0000000..257f890
--- /dev/null
+++ b/zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/impl/StatisticalAnalysisServiceImpl.java
@@ -0,0 +1,293 @@
+package com.zhitan.statisticalAnalysis.service.impl;
+
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateUtil;
+import com.zhitan.common.constant.CommonConst;
+import com.zhitan.common.constant.TimeTypeConst;
+import com.zhitan.common.enums.TimeType;
+import com.zhitan.dataitem.service.IDataItemService;
+import com.zhitan.model.domain.vo.ModelNodeIndexInfor;
+import com.zhitan.model.service.IModelNodeService;
+import com.zhitan.realtimedata.domain.DataItem;
+import com.zhitan.statisticalAnalysis.domain.dto.DataAnalysisMoMDTO;
+import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisMoMVO;
+import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisYoYVO;
+import com.zhitan.statisticalAnalysis.service.IStatisticalAnalysisService;
+import lombok.AllArgsConstructor;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 缁熻鍒嗘瀽  鎺ュ彛灞傚疄鐜板眰
+ */
+@Service
+@AllArgsConstructor
+public class StatisticalAnalysisServiceImpl implements IStatisticalAnalysisService {
+
+    private final IDataItemService dataItemService;
+
+    private final IModelNodeService modelNodeService;
+
+
+    /**
+     * 鑾峰彇鐢佃兘鑰楀悓姣旀暟鎹�
+     */
+    @Override
+    public List<DataAnalysisYoYVO> listElectricDataComparisonYoY(DataAnalysisMoMDTO dto) {
+        List<DataAnalysisYoYVO> yoyList = new ArrayList<>();
+        // 鏌ヨ鐐逛綅涓庣敤鑳藉崟鍏冧俊鎭�
+        List<ModelNodeIndexInfor> nodeInforList = listModelNodeIndexIdRelationInfor(dto.getNodeId());
+        if (CollectionUtils.isEmpty(nodeInforList)) {
+            return yoyList;
+        }
+        List<String> indexIds = nodeInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
+        // 鎸夌収鐐逛綅杩涜鍒嗙粍
+        Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = nodeInforList.stream().collect(
+                Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
+        // 鑾峰彇鏌ヨ鏃堕棿
+        Date beginTime = dto.getBeginTime();
+        Date endTime = dto.getEndTime();
+        // 鍚屾瘮鏃堕棿
+        Date lastTime = DateUtil.offset(beginTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
+        Date lastEndTime = DateUtil.offset(endTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
+        // 鏌ヨ瀵瑰簲indexIds锛屾壘鍒板搴攄ataItem淇℃伅
+        List<DataItem> dataItemList = dataItemService.getDataItemHourInforByIndexIds(beginTime, endTime, TimeType.HOUR.name(), indexIds);
+        List<DataItem> lastDataItemList = dataItemService.getDataItemHourInforByIndexIds(lastTime, lastEndTime, TimeType.HOUR.name(), indexIds);
+        //  鍊嶇巼
+        BigDecimal multiple = BigDecimal.valueOf(CommonConst.DIGIT_100);
+        nodeIndexMap.forEach((key, value) -> {
+            DataAnalysisYoYVO yoyVO = new DataAnalysisYoYVO();
+            Optional<ModelNodeIndexInfor> first = value.stream().findFirst();
+            first.ifPresent(modelNodeIndexInfor -> yoyVO.setEnergyUnitName(modelNodeIndexInfor.getName()));
+            // 璧嬪�煎崟浣�
+            yoyVO.setUnit("kWh");
+            // 鎵惧嚭indexIds
+            List<String> indexIdList = value.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
+            // 姹傚拰
+            BigDecimal sum = BigDecimal.valueOf(dataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
+                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
+            BigDecimal lastSum = BigDecimal.valueOf(lastDataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
+                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
+            yoyVO.setCurrentValue(sum);
+            yoyVO.setOldValue(lastSum);
+            //  鍚屾瘮鍊�
+            BigDecimal ratio = BigDecimal.ZERO;
+            if (lastSum.compareTo(BigDecimal.ZERO) != 0) {
+                ratio = sum.subtract(lastSum).divide(lastSum, CommonConst.DIGIT_2, RoundingMode.HALF_UP).multiply(multiple);
+            }
+            yoyVO.setRatio(ratio);
+            yoyList.add(yoyVO);
+        });
+        return yoyList;
+    }
+
+    /**
+     * 鑾峰彇鐢佃兘鑰楃幆姣旀暟鎹�
+     */
+    @Override
+    public List<DataAnalysisMoMVO> listElectricDataComparisonMoM(DataAnalysisMoMDTO dto) {
+        List<DataAnalysisMoMVO> momList = new ArrayList<>();
+        // 鏍规嵁id鏌ヨ鐐逛綅淇℃伅
+        List<ModelNodeIndexInfor> nodeIndexInforList = listModelNodeIndexIdRelationInfor(dto.getNodeId());
+        if (CollectionUtils.isEmpty(nodeIndexInforList)) {
+            return momList;
+        }
+        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
+        Date beginTime = dto.getBeginTime();
+        Date endTime = dto.getEndTime();
+        Date lastTime;
+        Date lastEndTime;
+        String queryTimeType = dto.getTimeType();
+        // 灏忔椂
+        if (TimeTypeConst.TIME_TYPE_HOUR.equals(queryTimeType)) {
+            lastTime = DateUtil.offsetHour(beginTime, CommonConst.DIGIT_MINUS_1);
+            lastEndTime = DateUtil.offsetHour(endTime, CommonConst.DIGIT_MINUS_1);
+            // 澶�
+        } else if (TimeTypeConst.TIME_TYPE_DAY.equals(queryTimeType)) {
+            lastTime = DateUtil.offsetDay(beginTime, CommonConst.DIGIT_MINUS_1);
+            lastEndTime = DateUtil.offsetDay(endTime, CommonConst.DIGIT_MINUS_1);
+            // 鏈�
+        } else if (TimeTypeConst.TIME_TYPE_MONTH.equals(queryTimeType)) {
+            lastTime = DateUtil.offsetMonth(beginTime, CommonConst.DIGIT_MINUS_1);
+            lastEndTime = DateUtil.offsetMonth(endTime, CommonConst.DIGIT_MINUS_1);
+            // 骞�
+        } else {
+            lastTime = DateUtil.offset(beginTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
+            lastEndTime = DateUtil.offset(endTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
+        }
+        // 鎸夌収鐐逛綅杩涜鍒嗙粍
+        Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = nodeIndexInforList.stream().collect(
+                Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
+        // 鏍规嵁indexId鏌ヨdataItem
+        List<DataItem> dataItemList = dataItemService.getDataItemHourInforByIndexIds(beginTime, endTime, TimeType.HOUR.name(), indexIds);
+        List<DataItem> lastDataItemList = dataItemService.getDataItemHourInforByIndexIds(lastTime, lastEndTime, TimeType.HOUR.name(), indexIds);
+        //  鍊嶇巼
+        BigDecimal multiple = BigDecimal.valueOf(CommonConst.DIGIT_100);
+        nodeIndexMap.forEach((key, value) -> {
+            DataAnalysisMoMVO momVO = new DataAnalysisMoMVO();
+            Optional<ModelNodeIndexInfor> first = value.stream().findFirst();
+            first.ifPresent(modelNodeIndexInfor -> momVO.setEnergyUnitName(modelNodeIndexInfor.getName()));
+            // 璧嬪�煎崟浣�
+            momVO.setUnit("kWh");
+            // 鎵惧嚭indexIds
+            List<String> indexIdList = value.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
+            // 姹傚拰
+            BigDecimal sum = BigDecimal.valueOf(dataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
+                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
+            BigDecimal lastSum = BigDecimal.valueOf(lastDataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
+                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
+            momVO.setCurrentValue(sum);
+            momVO.setOldValue(lastSum);
+            //  鍚屾瘮鍊�
+            BigDecimal ratio = BigDecimal.ZERO;
+            if (lastSum.compareTo(BigDecimal.ZERO) != 0) {
+                ratio = sum.subtract(lastSum).divide(lastSum, CommonConst.DIGIT_2, RoundingMode.HALF_UP).multiply(multiple);
+            }
+            momVO.setRatio(ratio);
+            momList.add(momVO);
+        });
+        return momList;
+    }
+
+    /**
+     * 鑾峰彇鑳借�楀悓姣旀暟鎹�
+     */
+    @Override
+    public List<DataAnalysisYoYVO> listWaterDataComparisonYoY(DataAnalysisMoMDTO dto) {
+        List<DataAnalysisYoYVO> yoyList = new ArrayList<>();
+        // 鏌ヨ鐐逛綅涓庣敤鑳藉崟鍏冧俊鎭�
+        List<ModelNodeIndexInfor> nodeInforList = listModelNodeIndexIdRelationInfor(dto.getNodeId());
+        if (CollectionUtils.isEmpty(nodeInforList)) {
+            return yoyList;
+        }
+        List<String> indexIds = nodeInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
+        // 鎸夌収鐐逛綅杩涜鍒嗙粍
+        Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = nodeInforList.stream().collect(
+                Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
+        // 鏃堕棿绫诲瀷
+        // 鑾峰彇鏌ヨ鏃堕棿
+        Date beginTime = dto.getBeginTime();
+        Date endTime = dto.getEndTime();
+        // 鍚屾瘮鏃堕棿
+        Date lastTime = DateUtil.offset(beginTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
+        Date lastEndTime = DateUtil.offset(endTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
+        // 鏌ヨ瀵瑰簲indexIds锛屾壘鍒板搴攄ataItem淇℃伅
+        List<DataItem> dataItemList = dataItemService.getDataItemHourInforByIndexIds(beginTime, endTime, TimeType.HOUR.name(), indexIds);
+        List<DataItem> lastDataItemList = dataItemService.getDataItemHourInforByIndexIds(lastTime, lastEndTime, TimeType.HOUR.name(), indexIds);
+        //  鍊嶇巼
+        BigDecimal multiple = BigDecimal.valueOf(CommonConst.DIGIT_100);
+        nodeIndexMap.forEach((key, value) -> {
+            DataAnalysisYoYVO yoyVO = new DataAnalysisYoYVO();
+            Optional<ModelNodeIndexInfor> first = value.stream().findFirst();
+            first.ifPresent(modelNodeIndexInfor -> yoyVO.setEnergyUnitName(modelNodeIndexInfor.getName()));
+            // 璧嬪�煎崟浣�
+            yoyVO.setUnit("m鲁");
+            // 鎵惧嚭indexIds
+            List<String> indexIdList = value.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
+            // 姹傚拰
+            BigDecimal sum = BigDecimal.valueOf(dataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
+                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
+            BigDecimal lastSum = BigDecimal.valueOf(lastDataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
+                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
+            yoyVO.setCurrentValue(sum);
+            yoyVO.setOldValue(lastSum);
+            //  鍚屾瘮鍊�
+            BigDecimal ratio = BigDecimal.ZERO;
+            if (lastSum.compareTo(BigDecimal.ZERO) != 0) {
+                ratio = sum.subtract(lastSum).divide(lastSum, CommonConst.DIGIT_2, RoundingMode.HALF_UP).multiply(multiple);
+            }
+            yoyVO.setRatio(ratio);
+            yoyList.add(yoyVO);
+        });
+        return yoyList;
+    }
+
+    /**
+     * 鑾峰彇鑳借�楃幆姣旀暟鎹�
+     */
+    @Override
+    public List<DataAnalysisMoMVO> listWaterDataComparisonMoM(DataAnalysisMoMDTO dto) {
+        List<DataAnalysisMoMVO> momList = new ArrayList<>();
+        // 鏍规嵁id鏌ヨ鐐逛綅淇℃伅
+        List<ModelNodeIndexInfor> nodeIndexInforList = listModelNodeIndexIdRelationInfor(dto.getNodeId());
+        if (CollectionUtils.isEmpty(nodeIndexInforList)) {
+            return momList;
+        }
+        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
+        Date beginTime = dto.getBeginTime();
+        Date endTime = dto.getEndTime();
+        Date lastTime;
+        Date lastEndTime;
+        String queryTimeType = dto.getTimeType();
+        // 灏忔椂
+        if (TimeTypeConst.TIME_TYPE_HOUR.equals(queryTimeType)) {
+            lastTime = DateUtil.offsetHour(beginTime, CommonConst.DIGIT_MINUS_1);
+            lastEndTime = DateUtil.offsetHour(endTime, CommonConst.DIGIT_MINUS_1);
+            // 澶�
+        } else if (TimeTypeConst.TIME_TYPE_DAY.equals(queryTimeType)) {
+            lastTime = DateUtil.offsetDay(beginTime, CommonConst.DIGIT_MINUS_1);
+            lastEndTime = DateUtil.offsetDay(endTime, CommonConst.DIGIT_MINUS_1);
+            // 鏈�
+        } else if (TimeTypeConst.TIME_TYPE_MONTH.equals(queryTimeType)) {
+            lastTime = DateUtil.offsetMonth(beginTime, CommonConst.DIGIT_MINUS_1);
+            lastEndTime = DateUtil.offsetMonth(endTime, CommonConst.DIGIT_MINUS_1);
+            // 骞�
+        } else {
+            lastTime = DateUtil.offset(beginTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
+            lastEndTime = DateUtil.offset(endTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
+        }
+        // 鎸夌収鐐逛綅杩涜鍒嗙粍
+        Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = nodeIndexInforList.stream().collect(
+                Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
+        // 鏌ヨ瀵瑰簲indexIds锛屾壘鍒板搴攄ataItem淇℃伅
+        List<DataItem> dataItemList = dataItemService.getDataItemHourInforByIndexIds(beginTime, endTime, TimeType.HOUR.name(), indexIds);
+        List<DataItem> lastDataItemList = dataItemService.getDataItemHourInforByIndexIds(lastTime, lastEndTime, TimeType.HOUR.name(), indexIds);
+        //  鍊嶇巼
+        BigDecimal multiple = BigDecimal.valueOf(CommonConst.DIGIT_100);
+        nodeIndexMap.forEach((key, value) -> {
+            DataAnalysisMoMVO momVO = new DataAnalysisMoMVO();
+            Optional<ModelNodeIndexInfor> first = value.stream().findFirst();
+            first.ifPresent(modelNodeIndexInfor -> momVO.setEnergyUnitName(modelNodeIndexInfor.getName()));
+            // 璧嬪�煎崟浣�
+            momVO.setUnit("m鲁");
+            // 鎵惧嚭indexIds
+            List<String> indexIdList = value.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
+            // 姹傚拰
+            BigDecimal sum = BigDecimal.valueOf(dataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
+                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
+            BigDecimal lastSum = BigDecimal.valueOf(lastDataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
+                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
+            momVO.setCurrentValue(sum);
+            momVO.setOldValue(lastSum);
+            //  鍚屾瘮鍊�
+            BigDecimal ratio = BigDecimal.ZERO;
+            if (lastSum.compareTo(BigDecimal.ZERO) != 0) {
+                ratio = sum.subtract(lastSum).divide(lastSum, CommonConst.DIGIT_2, RoundingMode.HALF_UP).multiply(multiple);
+            }
+            momVO.setRatio(ratio);
+            momList.add(momVO);
+        });
+        return momList;
+    }
+
+    /**
+     * 鏌ヨ鐐逛綅涓庣敤鑳藉崟鍏冧俊鎭�
+     */
+    private List<ModelNodeIndexInfor> listModelNodeIndexIdRelationInfor(String nodeId) {
+        List<ModelNodeIndexInfor> nodeInforList = modelNodeService.listModelNodeIndexIdRelationInforByParentId(nodeId);
+        // 濡傛灉鏄┖瀛樺湪涓ょ鎯呭喌锛�1锛歩d鏈夐棶棰橈紝2锛氭渶搴曞眰
+        if (CollectionUtils.isEmpty(nodeInforList)) {
+            List<ModelNodeIndexInfor> inforList = modelNodeService.getModelNodeIndexIdRelationInforByNodeId(nodeId);
+            if (CollectionUtils.isNotEmpty(inforList)) {
+                nodeInforList.addAll(inforList);
+            }
+        }
+        return nodeInforList;
+    }
+
+}
\ No newline at end of file
diff --git a/zhitan-system/src/main/resources/mapper/dataitem/DataItemMapper.xml b/zhitan-system/src/main/resources/mapper/dataitem/DataItemMapper.xml
index d64ec15..c6d65e1 100644
--- a/zhitan-system/src/main/resources/mapper/dataitem/DataItemMapper.xml
+++ b/zhitan-system/src/main/resources/mapper/dataitem/DataItemMapper.xml
@@ -199,4 +199,20 @@
         AND di.data_time BETWEEN   #{beginTime}  AND  #{endTime}
         AND di.time_type =  #{timeType}
     </select>
+
+    <select id="getDataItemHourInforByIndexIds" resultType="com.zhitan.realtimedata.domain.DataItem">
+        SELECT
+        index_id indexId,
+        data_time dataTime,
+        "value"
+        FROM
+        "data_item"
+        WHERE
+        index_id IN
+        <foreach collection="indexIds" item="indexId" open="(" separator="," close=")">
+            #{indexId}
+        </foreach>
+        AND ( begin_time BETWEEN #{beginTime} AND #{endTime} )
+        AND time_type = #{timeType}
+    </select>
 </mapper>
\ No newline at end of file

--
Gitblit v1.9.3