diff --git a/mh-admin/src/main/java/com/mh/web/controller/energy/ComprehensiveEnergyConsumptionController.java b/mh-admin/src/main/java/com/mh/web/controller/energy/ComprehensiveEnergyConsumptionController.java index 26c382e..0493458 100644 --- a/mh-admin/src/main/java/com/mh/web/controller/energy/ComprehensiveEnergyConsumptionController.java +++ b/mh-admin/src/main/java/com/mh/web/controller/energy/ComprehensiveEnergyConsumptionController.java @@ -5,11 +5,9 @@ import com.mh.common.core.domain.vo.EnergyQueryVO; import com.mh.common.core.page.TableDataInfo; import com.mh.common.utils.DateUtils; import com.mh.system.service.energy.IComprehensiveEnergyConsumptionService; +import com.mh.system.service.energy.IHistoryDataPreService; import org.springframework.beans.factory.annotation.Autowired; -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 org.springframework.web.bind.annotation.*; /** * @author LJF @@ -24,15 +22,48 @@ public class ComprehensiveEnergyConsumptionController extends BaseController { private final IComprehensiveEnergyConsumptionService comprehensiveEnergyConsumptionService; + private final IHistoryDataPreService historyDataPreService; + @Autowired - public ComprehensiveEnergyConsumptionController(IComprehensiveEnergyConsumptionService comprehensiveEnergyConsumptionService) { + public ComprehensiveEnergyConsumptionController(IComprehensiveEnergyConsumptionService comprehensiveEnergyConsumptionService, IHistoryDataPreService historyDataPreService) { this.comprehensiveEnergyConsumptionService = comprehensiveEnergyConsumptionService; + this.historyDataPreService = historyDataPreService; } + /** + * 能耗结构图 + * @param vo + * @return + */ @PostMapping("/struct") public TableDataInfo structure(@RequestBody EnergyQueryVO vo) { DateUtils.sysEnergyDateChange(vo); return getDataTable(comprehensiveEnergyConsumptionService.structure(vo)); } + /** + * 能耗钻取:实际上获取每个系统的用电能耗数据 + * @param vo + * @return + */ + @PostMapping("/drilling") + public TableDataInfo drilling(@RequestBody EnergyQueryVO vo) { + return getDataTable(comprehensiveEnergyConsumptionService.drilling(vo)); + } + + @GetMapping("/pre/topData") + public TableDataInfo getTopData(@RequestParam("systemType") String systemType, + @RequestParam(value = "deviceType", required = false) String deviceType) { + return getDataTable(historyDataPreService.getTopData(systemType, deviceType)); + } + + @GetMapping("/pre/echart") + public TableDataInfo getEnergyPre(@RequestParam("systemType") String systemType, + @RequestParam(value = "deviceType", required = false) String deviceType, + @RequestParam(value = "beginTime", required = false) String beginDate, + @RequestParam(value = "endTime", required = false) String endDate) { + return getDataTable(historyDataPreService.getEnergyPre(systemType, beginDate, endDate, deviceType)); + } + + } diff --git a/mh-common/src/main/java/com/mh/common/core/domain/dto/EnergyPreDTO.java b/mh-common/src/main/java/com/mh/common/core/domain/dto/EnergyPreDTO.java new file mode 100644 index 0000000..153a6b9 --- /dev/null +++ b/mh-common/src/main/java/com/mh/common/core/domain/dto/EnergyPreDTO.java @@ -0,0 +1,27 @@ +package com.mh.common.core.domain.dto; + +import lombok.Getter; +import lombok.Setter; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 用能预测前端类 + * @date 2024-05-09 17:31:27 + */ +@Setter +@Getter +public class EnergyPreDTO { + + /** + * 顶部数据 + */ + private EnergyPreTopDataDTO topData; + + /** + * 折线图数据 + */ + private EnergyPreEchartDataDTO echartData; + +} diff --git a/mh-common/src/main/java/com/mh/common/core/domain/dto/EnergyPreEchartDataDTO.java b/mh-common/src/main/java/com/mh/common/core/domain/dto/EnergyPreEchartDataDTO.java new file mode 100644 index 0000000..efda9b9 --- /dev/null +++ b/mh-common/src/main/java/com/mh/common/core/domain/dto/EnergyPreEchartDataDTO.java @@ -0,0 +1,37 @@ +package com.mh.common.core.domain.dto; + +import lombok.Getter; +import lombok.Setter; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 用能预测前端类 + * @date 2024-05-09 17:31:27 + */ +@Setter +@Getter +public class EnergyPreEchartDataDTO { + + /** + * 时间 + */ + private String curDate; + + /** + * 实际值 + */ + private String curData; + + /** + * 预测值 + */ + private String preData; + + /** + * 误差值 + */ + private String errorData; + +} diff --git a/mh-common/src/main/java/com/mh/common/core/domain/dto/EnergyPreTopDataDTO.java b/mh-common/src/main/java/com/mh/common/core/domain/dto/EnergyPreTopDataDTO.java new file mode 100644 index 0000000..5df890d --- /dev/null +++ b/mh-common/src/main/java/com/mh/common/core/domain/dto/EnergyPreTopDataDTO.java @@ -0,0 +1,37 @@ +package com.mh.common.core.domain.dto; + +import lombok.Getter; +import lombok.Setter; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 用能预测前端类 + * @date 2024-05-09 17:31:27 + */ +@Setter +@Getter +public class EnergyPreTopDataDTO { + + /** + * 昨日实际值 + */ + private String yesData; + + /** + * 昨日预测值 + */ + private String preYesData; + + /** + * 今日预测值 + */ + private String preCurData; + + /** + * 误差值 + */ + private String errorData; + +} diff --git a/mh-common/src/main/java/com/mh/common/core/domain/dto/EnergyStructureDTO.java b/mh-common/src/main/java/com/mh/common/core/domain/dto/EnergyStructureDTO.java index a869b82..dd174a7 100644 --- a/mh-common/src/main/java/com/mh/common/core/domain/dto/EnergyStructureDTO.java +++ b/mh-common/src/main/java/com/mh/common/core/domain/dto/EnergyStructureDTO.java @@ -14,7 +14,6 @@ import java.util.List; * @description 能源结构数据 * @date 2025-03-24 15:40:13 */ -@Setter @Getter public class EnergyStructureDTO { @@ -26,28 +25,84 @@ public class EnergyStructureDTO { /** * 能耗值 */ - private BigDecimal eng; + private BigDecimal curValue; /** - * 同比 + * 同比值 */ - private BigDecimal yny; + private BigDecimal yoyValue; /** - * 环比 + * 环比值 */ - private BigDecimal ono; + private BigDecimal momValue; + + /** + * 同比增长率 + */ + private BigDecimal yoyRate; + + /** + * 环比增长率 + */ + private BigDecimal momRate; private List children; + public void setLabel(String label) { + this.label = label; + } + + public void setCurValue(BigDecimal curValue) { + if (curValue == null) { + curValue = BigDecimal.ZERO; + } + this.curValue = curValue.setScale(2, BigDecimal.ROUND_HALF_UP); + } + + public void setYoyValue(BigDecimal yoyValue) { + if (yoyValue == null) { + yoyValue = BigDecimal.ZERO; + } + this.yoyValue = yoyValue.setScale(2, BigDecimal.ROUND_HALF_UP); + } + + public void setMomValue(BigDecimal momValue) { + if (momValue == null) { + momValue = BigDecimal.ZERO; + } + this.momValue = momValue.setScale(2, BigDecimal.ROUND_HALF_UP); + } + + public void setYoyRate(BigDecimal yoyRate) { + if (yoyRate == null) { + yoyRate = BigDecimal.ZERO; + } + this.yoyRate = yoyRate.setScale(2, BigDecimal.ROUND_HALF_UP); + } + + public void setMomRate(BigDecimal momRate) { + if (momRate == null) { + momRate = BigDecimal.ZERO; + } + this.momRate = momRate.setScale(2, BigDecimal.ROUND_HALF_UP); + } + + public void setChildren(List children) { + this.children = children; + } + @Override public String toString() { return new ToStringBuilder(this) .append("label", label) - .append("eng", eng) - .append("yny", yny) - .append("ono", ono) + .append("curValue", curValue) + .append("yoyValue", yoyValue) + .append("momValue", momValue) + .append("yoyRate", yoyRate) + .append("momRate", momRate) .append("children", children) .toString(); } + } diff --git a/mh-common/src/main/java/com/mh/common/core/domain/entity/HistoryDataPre.java b/mh-common/src/main/java/com/mh/common/core/domain/entity/HistoryDataPre.java new file mode 100644 index 0000000..5e89bf4 --- /dev/null +++ b/mh-common/src/main/java/com/mh/common/core/domain/entity/HistoryDataPre.java @@ -0,0 +1,65 @@ +package com.mh.common.core.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.builder.ToStringBuilder; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * @author LJF + * @version 1.0 + * @project EEMCS + * @description 用能预测值 + * @date 2025-03-25 15:14:22 + */ +@Setter +@Getter +@TableName("history_data_pre") +public class HistoryDataPre { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + private String systemType; + + private Date curDate; + + private BigDecimal envMinTemp; + + private BigDecimal envMaxTemp; + + private BigDecimal electValue; + + private BigDecimal waterValue; + + private BigDecimal waterLevel; + + private BigDecimal electValuePre; + + private BigDecimal waterValuePre; + + private BigDecimal waterLevelPre; + + @Override + public String toString() { + return new ToStringBuilder(this) + .append("id", id) + .append("systemType", systemType) + .append("curDate", curDate) + .append("envMinTemp", envMinTemp) + .append("envMaxTemp", envMaxTemp) + .append("electValue", electValue) + .append("waterValue", waterValue) + .append("waterLevel", waterLevel) + .append("electValuePre", electValuePre) + .append("waterValuePre", waterValuePre) + .append("waterLevelPre", waterLevelPre) + .toString(); + } + +} diff --git a/mh-system/src/main/java/com/mh/system/mapper/energy/ComprehensiveEnergyConsumptionMapper.java b/mh-system/src/main/java/com/mh/system/mapper/energy/ComprehensiveEnergyConsumptionMapper.java index 4a1a747..bce95f2 100644 --- a/mh-system/src/main/java/com/mh/system/mapper/energy/ComprehensiveEnergyConsumptionMapper.java +++ b/mh-system/src/main/java/com/mh/system/mapper/energy/ComprehensiveEnergyConsumptionMapper.java @@ -28,7 +28,7 @@ public interface ComprehensiveEnergyConsumptionMapper { * @return */ @Select("SELECT " + - " cpm.terminal_device_type as \"deviceType\", " + + " sdd.dict_label as \"label\", " + " cpm.system_type as \"systemType\", " + " SUM(COALESCE(dd.calc_value, 0)) as \"calcValue\" " + "FROM " + @@ -37,14 +37,19 @@ public interface ComprehensiveEnergyConsumptionMapper { " collection_params_manage cpm " + "ON " + " cpm.mt_num = dd.device_num " + + "JOIN " + + " sys_dict_data sdd " + + "ON " + + " cpm.terminal_device_type = sdd.dict_value " + "WHERE " + " cpm.grade = #{grade} " + " AND cpm.mt_is_sum = #{isSum} " + " AND cpm.param_type = #{paramType} " + " AND cpm.system_type = #{systemType} " + " AND dd.cur_time BETWEEN #{startTime}::timestamp AND #{endTime}::timestamp " + + " AND sdd.dict_type = 'sys_device_type' " + "GROUP BY " + - " cpm.terminal_device_type, " + + " sdd.dict_label, " + " cpm.system_type; ") List> selectOneTableData(@Param("tableName") String curTableName, @Param("isSum") int isSum, @@ -66,7 +71,7 @@ public interface ComprehensiveEnergyConsumptionMapper { * @return */ @Select("SELECT " + - " cpm.terminal_device_type as \"deviceType\", " + + " sdd.dict_label as \"label\", " + " cpm.system_type as \"systemType\", " + " SUM(COALESCE(dd.calc_value, 0)) as \"calcValue\" " + "FROM " + @@ -81,15 +86,20 @@ public interface ComprehensiveEnergyConsumptionMapper { " collection_params_manage cpm " + "ON " + " cpm.mt_num = dd.device_num " + + "JOIN " + + " sys_dict_data sdd " + + "ON " + + " cpm.terminal_device_type = sdd.dict_value " + "WHERE " + " cpm.grade = #{grade} " + " AND cpm.mt_is_sum = #{isSum} " + " AND cpm.param_type = #{paramType} " + " AND cpm.system_type = #{systemType} " + " AND dd.cur_time BETWEEN #{startTime}::timestamp AND #{endTime}::timestamp " + + " AND sdd.dict_type = 'sys_device_type' " + "GROUP BY " + - " cpm.terminal_device_type, " + - " cpm.system_type;") + " sdd.dict_label, " + + " cpm.system_type; ") List> selectMultiTableData(@Param("curTableName") String curTableName, @Param("lastTableName") String lastTableName, @Param("isSum") int isSum, diff --git a/mh-system/src/main/java/com/mh/system/mapper/energy/EnergyMapper.java b/mh-system/src/main/java/com/mh/system/mapper/energy/EnergyMapper.java index fd8ee70..8fa8950 100644 --- a/mh-system/src/main/java/com/mh/system/mapper/energy/EnergyMapper.java +++ b/mh-system/src/main/java/com/mh/system/mapper/energy/EnergyMapper.java @@ -60,6 +60,9 @@ public interface EnergyMapper { "" + " and cpm.system_type = #{systemType} " + "" + + "" + + " and cpm.param_type = #{paramType} " + + "" + ") " + "group by " + " device_type, " + @@ -108,6 +111,9 @@ public interface EnergyMapper { "" + " and cpm.system_type = #{systemType} " + "" + + "" + + " and cpm.param_type = #{paramType} " + + "" + ") " + "group by " + " device_type, " + @@ -173,6 +179,9 @@ public interface EnergyMapper { "" + " and cpm.system_type = #{systemType} " + "" + + "" + + " and cpm.param_type = #{paramType} " + + "" + ") " + "group by " + " device_type, " + diff --git a/mh-system/src/main/java/com/mh/system/mapper/energy/EnergyQueryMapper.java b/mh-system/src/main/java/com/mh/system/mapper/energy/EnergyQueryMapper.java index c33d232..6955b5a 100644 --- a/mh-system/src/main/java/com/mh/system/mapper/energy/EnergyQueryMapper.java +++ b/mh-system/src/main/java/com/mh/system/mapper/energy/EnergyQueryMapper.java @@ -60,6 +60,9 @@ public interface EnergyQueryMapper { " " + " and cpm.system_type = #{systemType} " + "" + + "" + + " and cpm.param_type = #{paramType} " + + "" + ") " + "group by " + " device_type, " + @@ -108,6 +111,9 @@ public interface EnergyQueryMapper { " " + " and cpm.system_type = #{systemType} " + "" + + "" + + " and cpm.param_type = #{paramType} " + + "" + ") " + "group by " + " device_type, " + @@ -175,6 +181,9 @@ public interface EnergyQueryMapper { " " + " and cpm.system_type = #{systemType} " + "" + + "" + + " and cpm.param_type = #{paramType} " + + "" + ") " + "group by " + " device_type, " + diff --git a/mh-system/src/main/java/com/mh/system/mapper/energy/HistoryDataPreMapper.java b/mh-system/src/main/java/com/mh/system/mapper/energy/HistoryDataPreMapper.java new file mode 100644 index 0000000..e749591 --- /dev/null +++ b/mh-system/src/main/java/com/mh/system/mapper/energy/HistoryDataPreMapper.java @@ -0,0 +1,119 @@ +package com.mh.system.mapper.energy; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.mh.common.core.domain.dto.EnergyPreEchartDataDTO; +import com.mh.common.core.domain.dto.EnergyPreTopDataDTO; +import com.mh.common.core.domain.entity.HistoryDataPre; +import org.apache.ibatis.annotations.*; + +import java.util.List; + +/** + * @author LJF + * @version 1.0 + * @project EEMCS + * @description 用能预测 + * @date 2025-03-25 16:55:58 + */ +@Mapper +public interface HistoryDataPreMapper extends BaseMapper { + + @Results({ + @Result(column = "pre_cur_data", property = "preCurData"), + @Result(column = "yes_data", property = "yesData"), + @Result(column = "pre_yes_data", property = "preYesData"), + @Result(column = "error_data", property = "errorData") + }) + @Select("") + List getTopData(@Param("systemType") String systemType, @Param("type") String type); + + @Results({ + @Result(column = "cur_date", property = "curDate"), + @Result(column = "cur_data", property = "curData"), + @Result(column = "pre_data", property = "preData"), + @Result(column = "error_data", property = "errorData") + }) + @Select("") + List getEnergyPre(@Param("systemType") String systemType, + @Param("beginDate") String beginDate, + @Param("endDate") String endDate, + @Param("type") String deviceType); + +} diff --git a/mh-system/src/main/java/com/mh/system/service/energy/IComprehensiveEnergyConsumptionService.java b/mh-system/src/main/java/com/mh/system/service/energy/IComprehensiveEnergyConsumptionService.java index 69955ee..4e26ce0 100644 --- a/mh-system/src/main/java/com/mh/system/service/energy/IComprehensiveEnergyConsumptionService.java +++ b/mh-system/src/main/java/com/mh/system/service/energy/IComprehensiveEnergyConsumptionService.java @@ -19,4 +19,12 @@ public interface IComprehensiveEnergyConsumptionService { * @return */ List structure(EnergyQueryVO vo); + + /** + * 能耗钻取:实际上获取每个系统的用电能耗数据 + * @param vo + * @return + */ + List drilling(EnergyQueryVO vo); + } diff --git a/mh-system/src/main/java/com/mh/system/service/energy/IHistoryDataPreService.java b/mh-system/src/main/java/com/mh/system/service/energy/IHistoryDataPreService.java new file mode 100644 index 0000000..75090f3 --- /dev/null +++ b/mh-system/src/main/java/com/mh/system/service/energy/IHistoryDataPreService.java @@ -0,0 +1,18 @@ +package com.mh.system.service.energy; + +import java.util.List; + +/** + * @author LJF + * @version 1.0 + * @project EEMCS + * @description 数据预测 + * @date 2025-03-25 15:36:29 + */ +public interface IHistoryDataPreService { + + List getTopData(String systemType, String deviceType); + + List getEnergyPre(String systemType, String beginDate, String endDate, String deviceType); + +} diff --git a/mh-system/src/main/java/com/mh/system/service/energy/impl/ComprehensiveEnergyConsumptionServiceImpl.java b/mh-system/src/main/java/com/mh/system/service/energy/impl/ComprehensiveEnergyConsumptionServiceImpl.java index be62623..f947b41 100644 --- a/mh-system/src/main/java/com/mh/system/service/energy/impl/ComprehensiveEnergyConsumptionServiceImpl.java +++ b/mh-system/src/main/java/com/mh/system/service/energy/impl/ComprehensiveEnergyConsumptionServiceImpl.java @@ -1,24 +1,34 @@ package com.mh.system.service.energy.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.mh.common.core.domain.AjaxResult; +import com.mh.common.core.domain.dto.EnergyConsumptionDTO; import com.mh.common.core.domain.dto.EnergyStructureDTO; import com.mh.common.core.domain.entity.CollectionParamsManage; +import com.mh.common.core.domain.entity.ConsumptionAnalyze; import com.mh.common.core.domain.entity.SysDictData; import com.mh.common.core.domain.entity.SysParams; import com.mh.common.core.domain.vo.EnergyQueryVO; import com.mh.common.utils.DateUtils; +import com.mh.common.utils.EnergyThreadPoolService; import com.mh.system.mapper.SysDictDataMapper; import com.mh.system.mapper.SysParamsMapper; import com.mh.system.mapper.device.CollectionParamsManageMapper; import com.mh.system.mapper.energy.ComprehensiveEnergyConsumptionMapper; +import com.mh.system.mapper.energy.EnergyMapper; +import com.mh.system.mapper.energy.EnergyQueryMapper; import com.mh.system.service.energy.IComprehensiveEnergyConsumptionService; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; /** * @author LJF @@ -27,6 +37,7 @@ import java.util.Map; * @description 综合能耗结构服务实现 * @date 2025-03-24 15:57:09 */ +@Slf4j @Service public class ComprehensiveEnergyConsumptionServiceImpl implements IComprehensiveEnergyConsumptionService { @@ -38,11 +49,98 @@ public class ComprehensiveEnergyConsumptionServiceImpl implements IComprehensive private final SysParamsMapper sysParamsMapper; - public ComprehensiveEnergyConsumptionServiceImpl(CollectionParamsManageMapper collectionParamsManageMapper, ComprehensiveEnergyConsumptionMapper comprehensiveEnergyConsumptionMapper, SysDictDataMapper sysDictDataMapper, SysParamsMapper sysParamsMapper) { + private final EnergyQueryMapper energyQueryMapper; + + public ComprehensiveEnergyConsumptionServiceImpl(CollectionParamsManageMapper collectionParamsManageMapper, + ComprehensiveEnergyConsumptionMapper comprehensiveEnergyConsumptionMapper, + SysDictDataMapper sysDictDataMapper, + SysParamsMapper sysParamsMapper, + EnergyQueryMapper energyQueryMapper) { this.collectionParamsManageMapper = collectionParamsManageMapper; this.comprehensiveEnergyConsumptionMapper = comprehensiveEnergyConsumptionMapper; this.sysDictDataMapper = sysDictDataMapper; this.sysParamsMapper = sysParamsMapper; + this.energyQueryMapper = energyQueryMapper; + } + + @Override + public List drilling(EnergyQueryVO vo) { + DateUtils.sysEnergyDateChange(vo); + // 获取参数 + AtomicReference lastTableName = new AtomicReference<>("data_" + vo.getTimeType()); + AtomicReference curTableName = new AtomicReference<>("data_" + vo.getTimeType()); + String timeType = vo.getTimeType(); + // 判断是否有总表 + boolean haveMeter = collectionParamsManageMapper.selectSummary(40, "5") != 0; + boolean haveCloud = collectionParamsManageMapper.selectSummary(40, "6") != 0; + List consumptionAnalyzeEntities = null; + // 表格数据 + if ("month".equalsIgnoreCase(timeType) || "year".equalsIgnoreCase(timeType)) { + // 单表 + consumptionAnalyzeEntities = energyQueryMapper.queryOneTable(vo.getStartTime(), vo.getEndTime(), lastTableName.get(), curTableName.get(), DateUtils.getTimeLen(vo.getTimeType()), vo.getParamType(), haveMeter, haveCloud, vo.getSystemType()); + } else { + lastTableName.set(lastTableName + vo.getStartTime().substring(0, 4)); + curTableName.set(curTableName + vo.getEndTime().substring(0, 4)); + if (lastTableName.get().equalsIgnoreCase(curTableName.get())) { + // 单表 + consumptionAnalyzeEntities = energyQueryMapper.queryOneTable(vo.getStartTime(), vo.getEndTime(), lastTableName.get(), curTableName.get(), DateUtils.getTimeLen(vo.getTimeType()), vo.getParamType(), haveMeter, haveCloud, vo.getSystemType()); + } else { + // 多表 + consumptionAnalyzeEntities = energyQueryMapper.queryManyTable(vo.getStartTime(), vo.getEndTime(), lastTableName.get(), curTableName.get(), DateUtils.getTimeLen(vo.getTimeType()), vo.getParamType(), haveMeter, haveCloud, vo.getSystemType()); + } + } + if (null == consumptionAnalyzeEntities || consumptionAnalyzeEntities.size() == 0) { + return List.of(); + } + // 分组并按时间排序操作,拿到冷量记和电表数据 + Map> collect = consumptionAnalyzeEntities.stream() + .parallel() + .collect(Collectors.groupingBy(ConsumptionAnalyze::getDeviceType, HashMap::new, Collectors + .collectingAndThen(Collectors.toList(), + list -> list.stream().sorted(Comparator.comparing(ConsumptionAnalyze::getTimeStr)).collect(Collectors.toList())))); + List meterData = new ArrayList<>(); + for (Map.Entry> nmap : collect.entrySet()) { + // 获取电表的值 + if (nmap.getKey().equalsIgnoreCase("meter")) { + meterData = nmap.getValue(); + } + } + String[] timeStrArr = meterData.stream() + .map(ConsumptionAnalyze::getTimeStr) + .toArray(String[]::new); + String[] meterArr = meterData.stream() + .map(ConsumptionAnalyze::getCurValue) + .toArray(String[]::new); + // 表格数据 + Map map = new HashMap<>(); + int pageNum = vo.getPageNum(); + int pageSize = vo.getPageSize(); + if (pageNum == 0) { + map.put("meterArr", meterArr); + map.put("timeStrArr", timeStrArr); + } else { + int startIndex = (pageNum-1)*pageSize; + int endIndex = Math.min(pageNum * pageSize, meterArr.length); + if (startIndex > endIndex) { + return List.of(); + } + map.put("meterArr", Arrays.copyOfRange(meterArr, startIndex , endIndex)); + map.put("timeStrArr", Arrays.copyOfRange(timeStrArr, startIndex , endIndex)); + } + + // 组装赋值 + List> listData = new ArrayList<>(); + Map meter = new HashMap<>(); + meter.put("meter", map.get("meterArr")); + listData.add(meter); + String[] titleArr = new String[]{"meter"}; + Map titles = new HashMap<>(); + titles.put("titleArr", titleArr); + listData.add(titles); + Map timeStr = new HashMap<>(); + timeStr.put("timeStrArr", map.get("timeStrArr")); + listData.add(timeStr); + return List.of(listData); } @Override @@ -85,13 +183,13 @@ public class ComprehensiveEnergyConsumptionServiceImpl implements IComprehensive // 流式拼接数据,根据map的deviceType,systemType两个分组拼接数据,得出deviceType, systemType, curValue, yoyValue, hbyValue // 得出新map,计算同比环比 for (Map map : structData) { - String deviceType = map.get("deviceType").toString(); + String deviceType = map.get("label").toString(); String systemType = map.get("systemType").toString(); // 当前值 map.put("curValue", map.get("calcValue") == null ? 0 : map.get("calcValue")); // 同比值 map.put("yoyValue", yoyStructData.stream() - .filter(item -> item.get("deviceType").equals(deviceType) + .filter(item -> item.get("label").equals(deviceType) && item.get("systemType").equals(systemType)) .findFirst() .map(item -> item.get("calcValue") == null ? 0 : item.get("calcValue")) @@ -100,12 +198,12 @@ public class ComprehensiveEnergyConsumptionServiceImpl implements IComprehensive // 同比率计算 BigDecimal curValue = new BigDecimal(String.valueOf(map.get("curValue"))); BigDecimal yoyValue = new BigDecimal(String.valueOf(map.get("yoyValue"))); - map.put("yoyRate", curValue.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO - : yoyValue.divide(curValue, 2, BigDecimal.ROUND_HALF_UP)); + map.put("yoyRate", yoyValue.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO + : (curValue.subtract(yoyValue)).divide(yoyValue).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP)); // 环比值 map.put("momValue", hbyStructData.stream() - .filter(item -> item.get("deviceType").equals(deviceType) + .filter(item -> item.get("label").equals(deviceType) && item.get("systemType").equals(systemType)) .findFirst() .map(item -> item.get("calcValue") == null ? 0 : item.get("calcValue")) @@ -113,8 +211,8 @@ public class ComprehensiveEnergyConsumptionServiceImpl implements IComprehensive // 环比率计算 BigDecimal momValue = new BigDecimal(String.valueOf(map.get("momValue"))); - map.put("momRate", curValue.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO - : momValue.divide(curValue, 2, BigDecimal.ROUND_HALF_UP)); + map.put("momRate", momValue.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO + : (curValue.subtract(momValue)).divide(momValue).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP)); } energyStructureDTO.setChildren(structData); @@ -122,10 +220,79 @@ public class ComprehensiveEnergyConsumptionServiceImpl implements IComprehensive result1.add(energyStructureDTO); } result.setChildren(result1); + // 得出结果,然后通过递归计算children上一层级的值,比如result的children,可以计算出result的curValue,yoyValue,momValue,yoyRate,momRate赋值给result对应值 + calculateParentValues(result); // 查询各个设备的能耗结构 return List.of(result); } + private void calculateParentValues(EnergyStructureDTO result) { + if (result.getChildren() == null || result.getChildren().isEmpty()) { + return; // 如果没有子节点,直接返回 + } + + double curValueSum = 0; + double yoyValueSum = 0; + double momValueSum = 0; + + // 遍历所有子节点,累加各个值 + for (Object child : result.getChildren()) { + if (child instanceof Map) { + Map childMap = (Map) child; + // 判断 curValue 是否为空 + if (childMap.get("curValue") != null) { + curValueSum += Double.parseDouble(childMap.get("curValue").toString()); + } + // 判断 yoyValue 是否为空 + if (childMap.get("yoyValue") != null) { + yoyValueSum += Double.parseDouble(childMap.get("yoyValue").toString()); + } + // 判断 momValue 是否为空 + if (childMap.get("momValue") != null) { + momValueSum += Double.parseDouble(childMap.get("momValue").toString()); + } + } else if (child instanceof EnergyStructureDTO) { + calculateParentValues((EnergyStructureDTO) child); // 递归计算子节点的值 + // 判断 curValue 是否为空 + if (((EnergyStructureDTO) child).getCurValue() != null) { + curValueSum += ((EnergyStructureDTO) child).getCurValue().doubleValue(); + } + // 判断 yoyValue 是否为空 + if (((EnergyStructureDTO) child).getYoyValue() != null) { + yoyValueSum += ((EnergyStructureDTO) child).getYoyValue().doubleValue(); + } + // 判断 momValue 是否为空 + if (((EnergyStructureDTO) child).getMomValue() != null) { + momValueSum += ((EnergyStructureDTO) child).getMomValue().doubleValue(); + } + } + } + + + // 设置当前节点的值 + result.setCurValue(BigDecimal.valueOf(curValueSum)); + result.setYoyValue(BigDecimal.valueOf(yoyValueSum)); + result.setMomValue(BigDecimal.valueOf(momValueSum)); + + // 计算同比和环比增长率 + if (result.getYoyValue().compareTo(BigDecimal.ZERO) != 0) { + result.setYoyRate((result.getCurValue().subtract(result.getYoyValue())) + .divide(result.getYoyValue()) + .multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP)); + } else { + result.setYoyRate(new BigDecimal(0)); + } + + if (result.getMomValue().compareTo(BigDecimal.ZERO) != 0) { + result.setMomRate((result.getCurValue().subtract(result.getMomValue())) + .divide(result.getMomValue()) + .multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP)); + } else { + result.setMomRate(new BigDecimal(0)); + } + } + + private List> getStructData(EnergyQueryVO vo, String systemType) { String startTime = vo.getStartTime().substring(0, 4); String endTime = vo.getEndTime().substring(0, 4); diff --git a/mh-system/src/main/java/com/mh/system/service/energy/impl/HistoryDataPreServiceImpl.java b/mh-system/src/main/java/com/mh/system/service/energy/impl/HistoryDataPreServiceImpl.java new file mode 100644 index 0000000..57fe872 --- /dev/null +++ b/mh-system/src/main/java/com/mh/system/service/energy/impl/HistoryDataPreServiceImpl.java @@ -0,0 +1,78 @@ +package com.mh.system.service.energy.impl; + +import com.mh.common.core.domain.dto.EnergyPreEchartDataDTO; +import com.mh.common.core.domain.dto.EnergyPreTopDataDTO; +import com.mh.common.utils.StringUtils; +import com.mh.system.mapper.energy.HistoryDataPreMapper; +import com.mh.system.service.energy.IHistoryDataPreService; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * @author LJF + * @version 1.0 + * @project EEMCS + * @description 数据预测 + * @date 2025-03-25 15:36:58 + */ +@Service +public class HistoryDataPreServiceImpl implements IHistoryDataPreService { + + private final HistoryDataPreMapper historyDataPreMapper; + + public HistoryDataPreServiceImpl(HistoryDataPreMapper historyDataPreMapper) { + this.historyDataPreMapper = historyDataPreMapper; + } + + @Override + public List getTopData(String systemType, String deviceType) { + return historyDataPreMapper.getTopData(systemType, deviceType); + } + + @Override + public List getEnergyPre(String systemType, String beginDate, String endDate, String deviceType) { + if (StringUtils.isBlank(beginDate) || StringUtils.isBlank(endDate)) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + // 获取当前日期 + LocalDate now = LocalDate.now(); + // 向前推30天 + LocalDate startDate = now.minusDays(30); + beginDate = startDate.format(formatter); + // 结束日期是当前日期 + endDate = now.format(formatter); + } + if (StringUtils.isBlank(systemType) || StringUtils.isBlank(deviceType)) { + return List.of(); + } + List energyPre = historyDataPreMapper.getEnergyPre(systemType, beginDate, endDate, deviceType); + if (energyPre.isEmpty()) { + return List.of(); + } + String[] curDate = energyPre.stream() + .map(EnergyPreEchartDataDTO::getCurDate) + .toArray(String[]::new); // 使用stream和map转换每个对象的特定字段为JSON字符串,然后转换成数组 + String[] curData = energyPre.stream() + .map(EnergyPreEchartDataDTO::getCurData) + .toArray(String[]::new); // 使用stream和map转换每个对象的特定字段为JSON字符串,然后转换成数组 + String[] preData = energyPre.stream() + .map(EnergyPreEchartDataDTO::getPreData) + .toArray(String[]::new); // 使用stream和map转换每个对象的特定字段为JSON字符串,然后转换成数组 + String[] errorData = energyPre.stream() + .map(EnergyPreEchartDataDTO::getErrorData) + .toArray(String[]::new); // 使用stream和map转换每个对象的特定字段为JSON字符串,然后转换成数组 + List> resultList = new ArrayList<>(); + HashMap resultHashMap = new HashMap<>(); + resultHashMap.put("curDate", curDate); + resultHashMap.put("curData", curData); + resultHashMap.put("preData", preData); + resultHashMap.put("errorData", errorData); + resultList.add(resultHashMap); + return resultList; + } + +} diff --git a/sql/表结构设计.sql b/sql/表结构设计.sql index 8701440..609b099 100644 --- a/sql/表结构设计.sql +++ b/sql/表结构设计.sql @@ -588,3 +588,37 @@ COMMENT ON COLUMN public.device_ledger.system_type IS '系统类型'; ALTER TABLE public.collection_params_manage ADD terminal_device_type varchar(10) NULL; COMMENT ON COLUMN public.collection_params_manage.terminal_device_type IS '终端设备类型'; + +-- 预测表结构值 +CREATE TABLE history_data_pre ( + cur_date DATE, + system_type VARCHAR(50), + env_min_temp NUMERIC(24,2), + env_max_temp NUMERIC(24,2), + water_value NUMERIC(24,2), + elect_value NUMERIC(24,2), + water_level NUMERIC(24,2), + id BIGSERIAL PRIMARY KEY, + water_value_pre NUMERIC(24,2), + elect_value_pre NUMERIC(24,2), + water_level_pre NUMERIC(24,2), + remark VARCHAR(200) +); + +CREATE INDEX history_data_pre_building_id ON history_data_pre (system_type ASC); +CREATE INDEX history_data_pre_cur_date ON history_data_pre (cur_date ASC); + +-- Extended properties +COMMENT ON TABLE history_data_pre IS '历史水电用量以及预测值'; +COMMENT ON COLUMN history_data_pre.cur_date IS '日期'; +COMMENT ON COLUMN history_data_pre.system_type IS '系统类型'; +COMMENT ON COLUMN history_data_pre.env_min_temp IS '环境最低温度'; +COMMENT ON COLUMN history_data_pre.env_max_temp IS '环境最高温度'; +COMMENT ON COLUMN history_data_pre.water_value IS '实际用水量'; +COMMENT ON COLUMN history_data_pre.elect_value IS '实际用电量'; +COMMENT ON COLUMN history_data_pre.water_level IS '平均水位'; +COMMENT ON COLUMN history_data_pre.id IS 'id'; +COMMENT ON COLUMN history_data_pre.water_value_pre IS '用水量预测值'; +COMMENT ON COLUMN history_data_pre.elect_value_pre IS '用电量预测值'; +COMMENT ON COLUMN history_data_pre.water_level_pre IS '平均水位预测值'; +COMMENT ON COLUMN history_data_pre.remark IS '备注';