Browse Source

1、综合能耗:能耗钻取、能耗预测接口。

dev
mh 1 month ago
parent
commit
514ccce742
  1. 41
      mh-admin/src/main/java/com/mh/web/controller/energy/ComprehensiveEnergyConsumptionController.java
  2. 27
      mh-common/src/main/java/com/mh/common/core/domain/dto/EnergyPreDTO.java
  3. 37
      mh-common/src/main/java/com/mh/common/core/domain/dto/EnergyPreEchartDataDTO.java
  4. 37
      mh-common/src/main/java/com/mh/common/core/domain/dto/EnergyPreTopDataDTO.java
  5. 73
      mh-common/src/main/java/com/mh/common/core/domain/dto/EnergyStructureDTO.java
  6. 65
      mh-common/src/main/java/com/mh/common/core/domain/entity/HistoryDataPre.java
  7. 20
      mh-system/src/main/java/com/mh/system/mapper/energy/ComprehensiveEnergyConsumptionMapper.java
  8. 9
      mh-system/src/main/java/com/mh/system/mapper/energy/EnergyMapper.java
  9. 9
      mh-system/src/main/java/com/mh/system/mapper/energy/EnergyQueryMapper.java
  10. 119
      mh-system/src/main/java/com/mh/system/mapper/energy/HistoryDataPreMapper.java
  11. 8
      mh-system/src/main/java/com/mh/system/service/energy/IComprehensiveEnergyConsumptionService.java
  12. 18
      mh-system/src/main/java/com/mh/system/service/energy/IHistoryDataPreService.java
  13. 191
      mh-system/src/main/java/com/mh/system/service/energy/impl/ComprehensiveEnergyConsumptionServiceImpl.java
  14. 78
      mh-system/src/main/java/com/mh/system/service/energy/impl/HistoryDataPreServiceImpl.java
  15. 34
      sql/表结构设计.sql

41
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));
}
}

27
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;
}

37
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;
}

37
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;
}

73
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();
}
}

65
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();
}
}

20
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<Map<String, Object>> 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<Map<String, Object>> selectMultiTableData(@Param("curTableName") String curTableName,
@Param("lastTableName") String lastTableName,
@Param("isSum") int isSum,

9
mh-system/src/main/java/com/mh/system/mapper/energy/EnergyMapper.java

@ -60,6 +60,9 @@ public interface EnergyMapper {
"<if test='systemType != null and systemType != \"\"'>" +
" and cpm.system_type = #{systemType} " +
"</if>" +
"<if test='paramType != null and paramType != \"\"'>" +
" and cpm.param_type = #{paramType} " +
"</if>" +
") " +
"group by " +
" device_type, " +
@ -108,6 +111,9 @@ public interface EnergyMapper {
"<if test='systemType != null and systemType != \"\"'>" +
" and cpm.system_type = #{systemType} " +
"</if>" +
"<if test='paramType != null and paramType != \"\"'>" +
" and cpm.param_type = #{paramType} " +
"</if>" +
") " +
"group by " +
" device_type, " +
@ -173,6 +179,9 @@ public interface EnergyMapper {
"<if test='systemType != null and systemType != \"\"'>" +
" and cpm.system_type = #{systemType} " +
"</if>" +
"<if test='paramType != null and paramType != \"\"'>" +
" and cpm.param_type = #{paramType} " +
"</if>" +
") " +
"group by " +
" device_type, " +

9
mh-system/src/main/java/com/mh/system/mapper/energy/EnergyQueryMapper.java

@ -60,6 +60,9 @@ public interface EnergyQueryMapper {
"<if test='systemType != null and systemType != \"\"'> " +
" and cpm.system_type = #{systemType} " +
"</if>" +
"<if test='paramType != null and paramType != \"\"'>" +
" and cpm.param_type = #{paramType} " +
"</if>" +
") " +
"group by " +
" device_type, " +
@ -108,6 +111,9 @@ public interface EnergyQueryMapper {
"<if test='systemType != null and systemType != \"\"'> " +
" and cpm.system_type = #{systemType} " +
"</if>" +
"<if test='paramType != null and paramType != \"\"'>" +
" and cpm.param_type = #{paramType} " +
"</if>" +
") " +
"group by " +
" device_type, " +
@ -175,6 +181,9 @@ public interface EnergyQueryMapper {
"<if test='systemType != null and systemType != \"\"'> " +
" and cpm.system_type = #{systemType} " +
"</if>" +
"<if test='paramType != null and paramType != \"\"'>" +
" and cpm.param_type = #{paramType} " +
"</if>" +
") " +
"group by " +
" device_type, " +

119
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<HistoryDataPre> {
@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("<script>" +
"SELECT " +
" <choose>" +
" <when test='type == \"2\"'>" +
" COALESCE(t.water_value_pre, 0) as pre_cur_data, " +
" COALESCE(t1.water_value, 0) as yes_data, " +
" COALESCE(t1.water_value_pre, 0) as pre_yes_data, " +
" CASE WHEN t1.water_value_pre > 0 THEN (ABS(COALESCE(t1.water_value_pre, 0) - COALESCE(t1.water_value, 0)) / t1.water_value_pre * 100)::numeric(18, 2) ELSE 0 END as error_data" +
" </when>" +
" <when test='type == \"5\"'>" +
" COALESCE(t.elect_value_pre, 0) as pre_cur_data, " +
" COALESCE(t1.elect_value, 0) as yes_data, " +
" COALESCE(t1.elect_value_pre, 0) as pre_yes_data, " +
" CASE WHEN t1.elect_value_pre > 0 THEN (ABS(COALESCE(t1.elect_value_pre, 0) - COALESCE(t1.elect_value, 0)) / t1.elect_value_pre * 100)::numeric(18, 2) ELSE 0 END as error_data" +
" </when>" +
" <when test='type == \"3\"'>" +
" COALESCE(t.water_level_pre, 0) as pre_cur_data, " +
" COALESCE(t1.water_level, 0) as yes_data, " +
" COALESCE(t1.water_level_pre, 0) as pre_yes_data, " +
" CASE WHEN t1.water_level_pre > 0 THEN (ABS(COALESCE(t1.water_level_pre, 0) - COALESCE(t1.water_level, 0)) / t1.water_level_pre * 100)::numeric(18, 2) ELSE 0 END as error_data" +
" </when>" +
" <otherwise>null</otherwise>" +
" </choose>" +
"FROM (" +
" SELECT " +
" system_type, " +
" water_value, " +
" elect_value, " +
" water_level, " +
" water_value_pre, " +
" elect_value_pre, " +
" water_level_pre " +
" FROM history_data_pre " +
" WHERE cur_date = CURRENT_DATE AND system_type = #{systemType}" +
") t " +
"JOIN (" +
" SELECT " +
" system_type, " +
" water_value, " +
" elect_value, " +
" water_level, " +
" water_value_pre, " +
" elect_value_pre, " +
" water_level_pre " +
" FROM history_data_pre " +
" WHERE cur_date = CURRENT_DATE - INTERVAL '1 day' AND system_type = #{systemType}" +
") t1 ON t.system_type = t1.system_type " +
"</script>")
List<EnergyPreTopDataDTO> 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("<script>" +
"SELECT " +
" hdp.cur_date, " +
" <choose>" +
" <when test='type == \"2\"'>COALESCE(hdp.water_value, 0)</when>" +
" <when test='type == \"5\"'>COALESCE(hdp.elect_value, 0)</when>" +
" <when test='type == \"3\"'>COALESCE(hdp.water_level, 0)</when>" +
" <otherwise>0</otherwise>" +
" </choose> as cur_data, " +
" <choose>" +
" <when test='type == \"2\"'>COALESCE(hdp.water_value_pre, 0)</when>" +
" <when test='type == \"5\"'>COALESCE(hdp.elect_value_pre, 0)</when>" +
" <when test='type == \"3\"'>COALESCE(hdp.water_level_pre, 0)</when>" +
" <otherwise>0</otherwise>" +
" </choose> as pre_data, " +
" CASE " +
" <when test='type == \"2\"'>" +
" WHEN hdp.water_value_pre > 0 THEN (ABS(COALESCE(hdp.water_value_pre, 0) - COALESCE(hdp.water_value, 0)) / hdp.water_value_pre * 100)::numeric(18, 2) ELSE 0 " +
" </when>" +
" <when test='type == \"5\"'>" +
" WHEN hdp.elect_value_pre > 0 THEN (ABS(COALESCE(hdp.elect_value_pre, 0) - COALESCE(hdp.elect_value, 0)) / hdp.elect_value_pre * 100)::numeric(18, 2) ELSE 0 " +
" </when>" +
" <when test='type == \"3\"'>" +
" WHEN hdp.water_level_pre > 0 THEN (ABS(COALESCE(hdp.water_level_pre, 0) - COALESCE(hdp.water_level, 0)) / hdp.water_level_pre * 100)::numeric(18, 2) ELSE 0 " +
" </when>" +
" END as error_data " +
"FROM history_data_pre hdp " +
"WHERE hdp.system_type = #{systemType} " +
" AND hdp.cur_date BETWEEN #{beginDate}::timestamp AND #{endDate}::timestamp " +
"ORDER BY hdp.cur_date" +
"</script>")
List<EnergyPreEchartDataDTO> getEnergyPre(@Param("systemType") String systemType,
@Param("beginDate") String beginDate,
@Param("endDate") String endDate,
@Param("type") String deviceType);
}

8
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);
}

18
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);
}

191
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<String> lastTableName = new AtomicReference<>("data_" + vo.getTimeType());
AtomicReference<String> 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<ConsumptionAnalyze> 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<String, List<ConsumptionAnalyze>> 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<ConsumptionAnalyze> meterData = new ArrayList<>();
for (Map.Entry<String, List<ConsumptionAnalyze>> 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<String, Object> 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<Map<String, Object>> listData = new ArrayList<>();
Map<String, Object> meter = new HashMap<>();
meter.put("meter", map.get("meterArr"));
listData.add(meter);
String[] titleArr = new String[]{"meter"};
Map<String, Object> titles = new HashMap<>();
titles.put("titleArr", titleArr);
listData.add(titles);
Map<String, Object> 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<String, Object> 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<String, Object> childMap = (Map<String, Object>) 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<Map<String, Object>> getStructData(EnergyQueryVO vo, String systemType) {
String startTime = vo.getStartTime().substring(0, 4);
String endTime = vo.getEndTime().substring(0, 4);

78
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<EnergyPreEchartDataDTO> 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<HashMap<String, Object>> resultList = new ArrayList<>();
HashMap<String, Object> resultHashMap = new HashMap<>();
resultHashMap.put("curDate", curDate);
resultHashMap.put("curData", curData);
resultHashMap.put("preData", preData);
resultHashMap.put("errorData", errorData);
resultList.add(resultHashMap);
return resultList;
}
}

34
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 '备注';

Loading…
Cancel
Save