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.core.page.TableDataInfo;
import com.mh.common.utils.DateUtils; import com.mh.common.utils.DateUtils;
import com.mh.system.service.energy.IComprehensiveEnergyConsumptionService; import com.mh.system.service.energy.IComprehensiveEnergyConsumptionService;
import com.mh.system.service.energy.IHistoryDataPreService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/** /**
* @author LJF * @author LJF
@ -24,15 +22,48 @@ public class ComprehensiveEnergyConsumptionController extends BaseController {
private final IComprehensiveEnergyConsumptionService comprehensiveEnergyConsumptionService; private final IComprehensiveEnergyConsumptionService comprehensiveEnergyConsumptionService;
private final IHistoryDataPreService historyDataPreService;
@Autowired @Autowired
public ComprehensiveEnergyConsumptionController(IComprehensiveEnergyConsumptionService comprehensiveEnergyConsumptionService) { public ComprehensiveEnergyConsumptionController(IComprehensiveEnergyConsumptionService comprehensiveEnergyConsumptionService, IHistoryDataPreService historyDataPreService) {
this.comprehensiveEnergyConsumptionService = comprehensiveEnergyConsumptionService; this.comprehensiveEnergyConsumptionService = comprehensiveEnergyConsumptionService;
this.historyDataPreService = historyDataPreService;
} }
/**
* 能耗结构图
* @param vo
* @return
*/
@PostMapping("/struct") @PostMapping("/struct")
public TableDataInfo structure(@RequestBody EnergyQueryVO vo) { public TableDataInfo structure(@RequestBody EnergyQueryVO vo) {
DateUtils.sysEnergyDateChange(vo); DateUtils.sysEnergyDateChange(vo);
return getDataTable(comprehensiveEnergyConsumptionService.structure(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 能源结构数据 * @description 能源结构数据
* @date 2025-03-24 15:40:13 * @date 2025-03-24 15:40:13
*/ */
@Setter
@Getter @Getter
public class EnergyStructureDTO { 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; 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 @Override
public String toString() { public String toString() {
return new ToStringBuilder(this) return new ToStringBuilder(this)
.append("label", label) .append("label", label)
.append("eng", eng) .append("curValue", curValue)
.append("yny", yny) .append("yoyValue", yoyValue)
.append("ono", ono) .append("momValue", momValue)
.append("yoyRate", yoyRate)
.append("momRate", momRate)
.append("children", children) .append("children", children)
.toString(); .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 * @return
*/ */
@Select("SELECT " + @Select("SELECT " +
" cpm.terminal_device_type as \"deviceType\", " + " sdd.dict_label as \"label\", " +
" cpm.system_type as \"systemType\", " + " cpm.system_type as \"systemType\", " +
" SUM(COALESCE(dd.calc_value, 0)) as \"calcValue\" " + " SUM(COALESCE(dd.calc_value, 0)) as \"calcValue\" " +
"FROM " + "FROM " +
@ -37,14 +37,19 @@ public interface ComprehensiveEnergyConsumptionMapper {
" collection_params_manage cpm " + " collection_params_manage cpm " +
"ON " + "ON " +
" cpm.mt_num = dd.device_num " + " cpm.mt_num = dd.device_num " +
"JOIN " +
" sys_dict_data sdd " +
"ON " +
" cpm.terminal_device_type = sdd.dict_value " +
"WHERE " + "WHERE " +
" cpm.grade = #{grade} " + " cpm.grade = #{grade} " +
" AND cpm.mt_is_sum = #{isSum} " + " AND cpm.mt_is_sum = #{isSum} " +
" AND cpm.param_type = #{paramType} " + " AND cpm.param_type = #{paramType} " +
" AND cpm.system_type = #{systemType} " + " AND cpm.system_type = #{systemType} " +
" AND dd.cur_time BETWEEN #{startTime}::timestamp AND #{endTime}::timestamp " + " AND dd.cur_time BETWEEN #{startTime}::timestamp AND #{endTime}::timestamp " +
" AND sdd.dict_type = 'sys_device_type' " +
"GROUP BY " + "GROUP BY " +
" cpm.terminal_device_type, " + " sdd.dict_label, " +
" cpm.system_type; ") " cpm.system_type; ")
List<Map<String, Object>> selectOneTableData(@Param("tableName") String curTableName, List<Map<String, Object>> selectOneTableData(@Param("tableName") String curTableName,
@Param("isSum") int isSum, @Param("isSum") int isSum,
@ -66,7 +71,7 @@ public interface ComprehensiveEnergyConsumptionMapper {
* @return * @return
*/ */
@Select("SELECT " + @Select("SELECT " +
" cpm.terminal_device_type as \"deviceType\", " + " sdd.dict_label as \"label\", " +
" cpm.system_type as \"systemType\", " + " cpm.system_type as \"systemType\", " +
" SUM(COALESCE(dd.calc_value, 0)) as \"calcValue\" " + " SUM(COALESCE(dd.calc_value, 0)) as \"calcValue\" " +
"FROM " + "FROM " +
@ -81,15 +86,20 @@ public interface ComprehensiveEnergyConsumptionMapper {
" collection_params_manage cpm " + " collection_params_manage cpm " +
"ON " + "ON " +
" cpm.mt_num = dd.device_num " + " cpm.mt_num = dd.device_num " +
"JOIN " +
" sys_dict_data sdd " +
"ON " +
" cpm.terminal_device_type = sdd.dict_value " +
"WHERE " + "WHERE " +
" cpm.grade = #{grade} " + " cpm.grade = #{grade} " +
" AND cpm.mt_is_sum = #{isSum} " + " AND cpm.mt_is_sum = #{isSum} " +
" AND cpm.param_type = #{paramType} " + " AND cpm.param_type = #{paramType} " +
" AND cpm.system_type = #{systemType} " + " AND cpm.system_type = #{systemType} " +
" AND dd.cur_time BETWEEN #{startTime}::timestamp AND #{endTime}::timestamp " + " AND dd.cur_time BETWEEN #{startTime}::timestamp AND #{endTime}::timestamp " +
" AND sdd.dict_type = 'sys_device_type' " +
"GROUP BY " + "GROUP BY " +
" cpm.terminal_device_type, " + " sdd.dict_label, " +
" cpm.system_type;") " cpm.system_type; ")
List<Map<String, Object>> selectMultiTableData(@Param("curTableName") String curTableName, List<Map<String, Object>> selectMultiTableData(@Param("curTableName") String curTableName,
@Param("lastTableName") String lastTableName, @Param("lastTableName") String lastTableName,
@Param("isSum") int isSum, @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 != \"\"'>" + "<if test='systemType != null and systemType != \"\"'>" +
" and cpm.system_type = #{systemType} " + " and cpm.system_type = #{systemType} " +
"</if>" + "</if>" +
"<if test='paramType != null and paramType != \"\"'>" +
" and cpm.param_type = #{paramType} " +
"</if>" +
") " + ") " +
"group by " + "group by " +
" device_type, " + " device_type, " +
@ -108,6 +111,9 @@ public interface EnergyMapper {
"<if test='systemType != null and systemType != \"\"'>" + "<if test='systemType != null and systemType != \"\"'>" +
" and cpm.system_type = #{systemType} " + " and cpm.system_type = #{systemType} " +
"</if>" + "</if>" +
"<if test='paramType != null and paramType != \"\"'>" +
" and cpm.param_type = #{paramType} " +
"</if>" +
") " + ") " +
"group by " + "group by " +
" device_type, " + " device_type, " +
@ -173,6 +179,9 @@ public interface EnergyMapper {
"<if test='systemType != null and systemType != \"\"'>" + "<if test='systemType != null and systemType != \"\"'>" +
" and cpm.system_type = #{systemType} " + " and cpm.system_type = #{systemType} " +
"</if>" + "</if>" +
"<if test='paramType != null and paramType != \"\"'>" +
" and cpm.param_type = #{paramType} " +
"</if>" +
") " + ") " +
"group by " + "group by " +
" device_type, " + " 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 != \"\"'> " + "<if test='systemType != null and systemType != \"\"'> " +
" and cpm.system_type = #{systemType} " + " and cpm.system_type = #{systemType} " +
"</if>" + "</if>" +
"<if test='paramType != null and paramType != \"\"'>" +
" and cpm.param_type = #{paramType} " +
"</if>" +
") " + ") " +
"group by " + "group by " +
" device_type, " + " device_type, " +
@ -108,6 +111,9 @@ public interface EnergyQueryMapper {
"<if test='systemType != null and systemType != \"\"'> " + "<if test='systemType != null and systemType != \"\"'> " +
" and cpm.system_type = #{systemType} " + " and cpm.system_type = #{systemType} " +
"</if>" + "</if>" +
"<if test='paramType != null and paramType != \"\"'>" +
" and cpm.param_type = #{paramType} " +
"</if>" +
") " + ") " +
"group by " + "group by " +
" device_type, " + " device_type, " +
@ -175,6 +181,9 @@ public interface EnergyQueryMapper {
"<if test='systemType != null and systemType != \"\"'> " + "<if test='systemType != null and systemType != \"\"'> " +
" and cpm.system_type = #{systemType} " + " and cpm.system_type = #{systemType} " +
"</if>" + "</if>" +
"<if test='paramType != null and paramType != \"\"'>" +
" and cpm.param_type = #{paramType} " +
"</if>" +
") " + ") " +
"group by " + "group by " +
" device_type, " + " 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 * @return
*/ */
List<?> structure(EnergyQueryVO vo); 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; package com.mh.system.service.energy.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 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.dto.EnergyStructureDTO;
import com.mh.common.core.domain.entity.CollectionParamsManage; 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.SysDictData;
import com.mh.common.core.domain.entity.SysParams; import com.mh.common.core.domain.entity.SysParams;
import com.mh.common.core.domain.vo.EnergyQueryVO; import com.mh.common.core.domain.vo.EnergyQueryVO;
import com.mh.common.utils.DateUtils; import com.mh.common.utils.DateUtils;
import com.mh.common.utils.EnergyThreadPoolService;
import com.mh.system.mapper.SysDictDataMapper; import com.mh.system.mapper.SysDictDataMapper;
import com.mh.system.mapper.SysParamsMapper; import com.mh.system.mapper.SysParamsMapper;
import com.mh.system.mapper.device.CollectionParamsManageMapper; import com.mh.system.mapper.device.CollectionParamsManageMapper;
import com.mh.system.mapper.energy.ComprehensiveEnergyConsumptionMapper; 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 com.mh.system.service.energy.IComprehensiveEnergyConsumptionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap; import java.util.concurrent.CountDownLatch;
import java.util.List; import java.util.concurrent.ExecutionException;
import java.util.Map; import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
/** /**
* @author LJF * @author LJF
@ -27,6 +37,7 @@ import java.util.Map;
* @description 综合能耗结构服务实现 * @description 综合能耗结构服务实现
* @date 2025-03-24 15:57:09 * @date 2025-03-24 15:57:09
*/ */
@Slf4j
@Service @Service
public class ComprehensiveEnergyConsumptionServiceImpl implements IComprehensiveEnergyConsumptionService { public class ComprehensiveEnergyConsumptionServiceImpl implements IComprehensiveEnergyConsumptionService {
@ -38,11 +49,98 @@ public class ComprehensiveEnergyConsumptionServiceImpl implements IComprehensive
private final SysParamsMapper sysParamsMapper; 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.collectionParamsManageMapper = collectionParamsManageMapper;
this.comprehensiveEnergyConsumptionMapper = comprehensiveEnergyConsumptionMapper; this.comprehensiveEnergyConsumptionMapper = comprehensiveEnergyConsumptionMapper;
this.sysDictDataMapper = sysDictDataMapper; this.sysDictDataMapper = sysDictDataMapper;
this.sysParamsMapper = sysParamsMapper; 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 @Override
@ -85,13 +183,13 @@ public class ComprehensiveEnergyConsumptionServiceImpl implements IComprehensive
// 流式拼接数据,根据map的deviceType,systemType两个分组拼接数据,得出deviceType, systemType, curValue, yoyValue, hbyValue // 流式拼接数据,根据map的deviceType,systemType两个分组拼接数据,得出deviceType, systemType, curValue, yoyValue, hbyValue
// 得出新map,计算同比环比 // 得出新map,计算同比环比
for (Map<String, Object> map : structData) { for (Map<String, Object> map : structData) {
String deviceType = map.get("deviceType").toString(); String deviceType = map.get("label").toString();
String systemType = map.get("systemType").toString(); String systemType = map.get("systemType").toString();
// 当前值 // 当前值
map.put("curValue", map.get("calcValue") == null ? 0 : map.get("calcValue")); map.put("curValue", map.get("calcValue") == null ? 0 : map.get("calcValue"));
// 同比值 // 同比值
map.put("yoyValue", yoyStructData.stream() map.put("yoyValue", yoyStructData.stream()
.filter(item -> item.get("deviceType").equals(deviceType) .filter(item -> item.get("label").equals(deviceType)
&& item.get("systemType").equals(systemType)) && item.get("systemType").equals(systemType))
.findFirst() .findFirst()
.map(item -> item.get("calcValue") == null ? 0 : item.get("calcValue")) .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 curValue = new BigDecimal(String.valueOf(map.get("curValue")));
BigDecimal yoyValue = new BigDecimal(String.valueOf(map.get("yoyValue"))); BigDecimal yoyValue = new BigDecimal(String.valueOf(map.get("yoyValue")));
map.put("yoyRate", curValue.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO map.put("yoyRate", yoyValue.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO
: yoyValue.divide(curValue, 2, BigDecimal.ROUND_HALF_UP)); : (curValue.subtract(yoyValue)).divide(yoyValue).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP));
// 环比值 // 环比值
map.put("momValue", hbyStructData.stream() map.put("momValue", hbyStructData.stream()
.filter(item -> item.get("deviceType").equals(deviceType) .filter(item -> item.get("label").equals(deviceType)
&& item.get("systemType").equals(systemType)) && item.get("systemType").equals(systemType))
.findFirst() .findFirst()
.map(item -> item.get("calcValue") == null ? 0 : item.get("calcValue")) .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"))); BigDecimal momValue = new BigDecimal(String.valueOf(map.get("momValue")));
map.put("momRate", curValue.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO map.put("momRate", momValue.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO
: momValue.divide(curValue, 2, BigDecimal.ROUND_HALF_UP)); : (curValue.subtract(momValue)).divide(momValue).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP));
} }
energyStructureDTO.setChildren(structData); energyStructureDTO.setChildren(structData);
@ -122,10 +220,79 @@ public class ComprehensiveEnergyConsumptionServiceImpl implements IComprehensive
result1.add(energyStructureDTO); result1.add(energyStructureDTO);
} }
result.setChildren(result1); result.setChildren(result1);
// 得出结果,然后通过递归计算children上一层级的值,比如result的children,可以计算出result的curValue,yoyValue,momValue,yoyRate,momRate赋值给result对应值
calculateParentValues(result);
// 查询各个设备的能耗结构 // 查询各个设备的能耗结构
return List.of(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) { private List<Map<String, Object>> getStructData(EnergyQueryVO vo, String systemType) {
String startTime = vo.getStartTime().substring(0, 4); String startTime = vo.getStartTime().substring(0, 4);
String endTime = vo.getEndTime().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; ALTER TABLE public.collection_params_manage ADD terminal_device_type varchar(10) NULL;
COMMENT ON COLUMN public.collection_params_manage.terminal_device_type IS '终端设备类型'; 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