15 changed files with 588 additions and 21 deletions
@ -0,0 +1,34 @@
|
||||
package com.mh.web.controller.comprehensive; |
||||
|
||||
import com.mh.common.core.controller.BaseController; |
||||
import com.mh.common.core.domain.vo.EnergyQueryVO; |
||||
import com.mh.common.core.page.TableDataInfo; |
||||
import com.mh.system.service.report.IComprehensiveReportService; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.RequestBody; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
/** |
||||
* @Classname CompreReportController |
||||
* Todo: 综合报表 |
||||
* @Date 2025-10-05 13:59 |
||||
* @Created by LJF |
||||
*/ |
||||
@RestController |
||||
@RequestMapping("/compre") |
||||
public class CompreReportController extends BaseController { |
||||
|
||||
private final IComprehensiveReportService proOverviewService; |
||||
|
||||
public CompreReportController(IComprehensiveReportService proOverviewService) { |
||||
this.proOverviewService = proOverviewService; |
||||
} |
||||
|
||||
@GetMapping("/report") |
||||
public TableDataInfo report(@RequestBody EnergyQueryVO vo) { |
||||
startPage(); |
||||
return getDataTable(proOverviewService.report(vo)); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,209 @@
|
||||
package com.mh.system.mapper.report; |
||||
|
||||
import com.mh.common.core.domain.ColumnFilter; |
||||
import com.mh.common.core.domain.entity.CollectionParamsManage; |
||||
import com.mh.common.core.domain.entity.WaterLevel; |
||||
import org.apache.ibatis.annotations.*; |
||||
|
||||
import java.math.BigDecimal; |
||||
import java.util.Date; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author LJF |
||||
* @version 1.0 |
||||
* @project EEMCS |
||||
* @description 热水温度记录 |
||||
* @date 2025-06-19 16:24:31 |
||||
*/ |
||||
@Mapper |
||||
public interface ComprehensiveReportMapper { |
||||
|
||||
|
||||
@Select("<script>" + |
||||
"select sum(calc_value) as calc_value from data_year where " + |
||||
" cur_time >= DATE_TRUNC('year', CURRENT_DATE)" + |
||||
" AND cur_time < DATE_TRUNC('year', CURRENT_DATE) + INTERVAL '1 year'" + |
||||
" <if test='deviceNums != null and deviceNums.size() > 0'>" + |
||||
" AND device_num IN " + |
||||
" <foreach collection='deviceNums' item='item' open='(' separator=',' close=')'>" + |
||||
" #{item.mtNum} " + |
||||
" </foreach>" + |
||||
" </if>" + |
||||
"</script>") |
||||
BigDecimal queryByDeviceNum(@Param("deviceNums") List<CollectionParamsManage> deviceNums); |
||||
|
||||
@Select("<script>" + |
||||
"WITH periods AS ( " + |
||||
" SELECT " + |
||||
" <choose>" + |
||||
" <when test='timeType == \"year\"'>" + |
||||
" to_char(generate_series( " + |
||||
" date_trunc('year', #{startTime}::timestamp), " + |
||||
" date_trunc('year', #{endTime}::timestamp), " + |
||||
" '1 year' " + |
||||
" ), 'YYYY') AS period " + |
||||
" </when>" + |
||||
" <when test='timeType == \"month\"'>" + |
||||
" to_char(generate_series( " + |
||||
" date_trunc('month', #{startTime}::timestamp), " + |
||||
" date_trunc('month', #{endTime}::timestamp), " + |
||||
" '1 month' " + |
||||
" ), 'YYYY-MM') AS period " + |
||||
" </when>" + |
||||
" <when test='timeType == \"day\"'>" + |
||||
" to_char(generate_series( " + |
||||
" date_trunc('day', #{startTime}::timestamp), " + |
||||
" date_trunc('day', #{endTime}::timestamp), " + |
||||
" '1 day' " + |
||||
" ), 'YYYY-MM-DD') AS period " + |
||||
" </when>" + |
||||
" <when test='timeType == \"hour\"'>" + |
||||
" to_char(generate_series( " + |
||||
" date_trunc('hour', #{startTime}::timestamp), " + |
||||
" date_trunc('hour', #{endTime}::timestamp), " + |
||||
" '1 hour' " + |
||||
" ), 'YYYY-MM-DD HH24') AS period " + |
||||
" </when>" + |
||||
" <otherwise>" + |
||||
" to_char(generate_series( " + |
||||
" date_trunc('month', #{startTime}::timestamp), " + |
||||
" date_trunc('month', #{endTime}::timestamp), " + |
||||
" '1 month' " + |
||||
" ), 'YYYY-MM') AS period " + |
||||
" </otherwise>" + |
||||
" </choose>" + |
||||
") " + |
||||
"SELECT " + |
||||
" p.period as name, " + |
||||
" COALESCE(SUM(all_data.calc_value), 0) AS value " + |
||||
"FROM periods p " + |
||||
"LEFT JOIN ( " + |
||||
" SELECT cur_time, calc_value, device_num FROM ${lastTableName} " + |
||||
" WHERE cur_time >= #{startTime} AND cur_time <= #{endTime} " + |
||||
" UNION ALL " + |
||||
" SELECT cur_time, calc_value, device_num FROM ${curTableName} " + |
||||
" WHERE cur_time >= #{startTime} AND cur_time <= #{endTime} " + |
||||
") all_data ON <choose>" + |
||||
" <when test='timeType == \"year\"'>" + |
||||
" to_char(all_data.cur_time, 'YYYY') = p.period " + |
||||
" </when>" + |
||||
" <when test='timeType == \"month\"'>" + |
||||
" to_char(all_data.cur_time, 'YYYY-MM') = p.period " + |
||||
" </when>" + |
||||
" <when test='timeType == \"day\"'>" + |
||||
" to_char(all_data.cur_time, 'YYYY-MM-DD') = p.period " + |
||||
" </when>" + |
||||
" <when test='timeType == \"hour\"'>" + |
||||
" to_char(all_data.cur_time, 'YYYY-MM-DD HH24') = p.period " + |
||||
" </when>" + |
||||
" <otherwise>" + |
||||
" to_char(all_data.cur_time, 'YYYY-MM') = p.period " + |
||||
" </otherwise>" + |
||||
" </choose>" + |
||||
" <if test='deviceNums != null and deviceNums.size() > 0'>" + |
||||
" AND all_data.device_num IN " + |
||||
" <foreach collection='deviceNums' item='item' open='(' separator=',' close=')'>" + |
||||
" #{item.mtNum} " + |
||||
" </foreach>" + |
||||
" </if>" + |
||||
"GROUP BY p.period " + |
||||
"ORDER BY p.period; " + |
||||
"</script>") |
||||
List<ColumnFilter> energyAnalysisManyTable(@Param("deviceNums") List<CollectionParamsManage> deviceNums, |
||||
@Param("lastTableName") String lastTableName, |
||||
@Param("curTableName") String curTableName, |
||||
@Param("startTime") Date startTime, |
||||
@Param("endTime") Date endTime, |
||||
@Param("timeType") String timeType); |
||||
|
||||
@Select("<script>" + |
||||
"select sum(cur_value) from collect_param_manage where id in " + |
||||
" <foreach collection='deviceNums' item='item' open='(' separator=',' close=')'>" + |
||||
" #{item.id} " + |
||||
" </foreach>" + |
||||
"</script>") |
||||
BigDecimal selectEER(@Param("deviceNums") List<CollectionParamsManage> deviceNums); |
||||
|
||||
@Select("<script>" + |
||||
"WITH periods AS ( " + |
||||
" SELECT " + |
||||
" <choose>" + |
||||
" <when test='timeType == \"year\"'>" + |
||||
" to_char(generate_series( " + |
||||
" date_trunc('year', #{startTime}::timestamp), " + |
||||
" date_trunc('year', #{endTime}::timestamp), " + |
||||
" '1 year' " + |
||||
" ), 'YYYY') AS period " + |
||||
" </when>" + |
||||
" <when test='timeType == \"month\"'>" + |
||||
" to_char(generate_series( " + |
||||
" date_trunc('month', #{startTime}::timestamp), " + |
||||
" date_trunc('month', #{endTime}::timestamp), " + |
||||
" '1 month' " + |
||||
" ), 'YYYY-MM') AS period " + |
||||
" </when>" + |
||||
" <when test='timeType == \"day\"'>" + |
||||
" to_char(generate_series( " + |
||||
" date_trunc('day', #{startTime}::timestamp), " + |
||||
" date_trunc('day', #{endTime}::timestamp), " + |
||||
" '1 day' " + |
||||
" ), 'YYYY-MM-DD') AS period " + |
||||
" </when>" + |
||||
" <when test='timeType == \"hour\"'>" + |
||||
" to_char(generate_series( " + |
||||
" date_trunc('hour', #{startTime}::timestamp), " + |
||||
" date_trunc('hour', #{endTime}::timestamp), " + |
||||
" '1 hour' " + |
||||
" ), 'YYYY-MM-DD HH24') AS period " + |
||||
" </when>" + |
||||
" <otherwise>" + |
||||
" to_char(generate_series( " + |
||||
" date_trunc('month', #{startTime}::timestamp), " + |
||||
" date_trunc('month', #{endTime}::timestamp), " + |
||||
" '1 month' " + |
||||
" ), 'YYYY-MM') AS period " + |
||||
" </otherwise>" + |
||||
" </choose>" + |
||||
") " + |
||||
"SELECT " + |
||||
" p.period as name, " + |
||||
" COALESCE(SUM(dm.calc_value), 0) AS value " + |
||||
"FROM periods p " + |
||||
"LEFT JOIN ${lastTableName} dm " + |
||||
" ON <choose>" + |
||||
" <when test='timeType == \"year\"'>" + |
||||
" to_char(dm.cur_time, 'YYYY') = p.period " + |
||||
" </when>" + |
||||
" <when test='timeType == \"month\"'>" + |
||||
" to_char(dm.cur_time, 'YYYY-MM') = p.period " + |
||||
" </when>" + |
||||
" <when test='timeType == \"day\"'>" + |
||||
" to_char(dm.cur_time, 'YYYY-MM-DD') = p.period " + |
||||
" </when>" + |
||||
" <when test='timeType == \"hour\"'>" + |
||||
" to_char(dm.cur_time, 'YYYY-MM-DD HH24') = p.period " + |
||||
" </when>" + |
||||
" <otherwise>" + |
||||
" to_char(dm.cur_time, 'YYYY-MM') = p.period " + |
||||
" </otherwise>" + |
||||
" </choose>" + |
||||
" <if test='deviceNums != null and deviceNums.size() > 0'>" + |
||||
" AND dm.device_num IN " + |
||||
" <foreach collection='deviceNums' item='item' open='(' separator=',' close=')'>" + |
||||
" #{item.mtNum} " + |
||||
" </foreach>" + |
||||
" </if>" + |
||||
" AND dm.cur_time >= #{startTime} AND dm.cur_time <= #{endTime} " + |
||||
"GROUP BY p.period " + |
||||
"ORDER BY p.period; " + |
||||
"</script>") |
||||
List<ColumnFilter> energyAnalysisOneTable(@Param("deviceNums") List<CollectionParamsManage> deviceNums, |
||||
@Param("lastTableName") String lastTableName, |
||||
@Param("curTableName") String curTableName, |
||||
@Param("startTime") Date startTime, |
||||
@Param("endTime") Date endTime, |
||||
@Param("timeType") String timeType); |
||||
|
||||
} |
@ -0,0 +1,14 @@
|
||||
package com.mh.system.service.report; |
||||
|
||||
import com.mh.common.core.domain.vo.EnergyQueryVO; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @Description: 综合能耗报表 |
||||
* @Author: LJF |
||||
* @Date: 2020/4/1 10:03 |
||||
**/ |
||||
public interface IComprehensiveReportService { |
||||
List<?> report(EnergyQueryVO vo); |
||||
} |
@ -0,0 +1,206 @@
|
||||
package com.mh.system.service.report.impl; |
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
||||
import com.mh.common.core.domain.ColumnFilter; |
||||
import com.mh.common.core.domain.dto.OverviewEnergyDTO; |
||||
import com.mh.common.core.domain.entity.CollectionParamsManage; |
||||
import com.mh.common.core.domain.entity.SysDictData; |
||||
import com.mh.common.core.domain.vo.EnergyQueryVO; |
||||
import com.mh.common.utils.DateUtils; |
||||
import com.mh.system.mapper.SysDictDataMapper; |
||||
import com.mh.system.mapper.device.CollectionParamsManageMapper; |
||||
import com.mh.system.mapper.report.ComprehensiveReportMapper; |
||||
import com.mh.system.service.report.IComprehensiveReportService; |
||||
import jakarta.annotation.Resource; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
import java.math.BigDecimal; |
||||
import java.time.LocalDate; |
||||
import java.util.*; |
||||
import java.util.concurrent.atomic.AtomicReference; |
||||
import java.util.stream.Collectors; |
||||
|
||||
/** |
||||
* @Classname ComprehensiveReportServiceImpl |
||||
* Todo: 综合能耗数据报表 |
||||
* @Date 2025-10-05 14:05 |
||||
* @Created by LJF |
||||
*/ |
||||
@Service |
||||
public class ComprehensiveReportServiceImpl implements IComprehensiveReportService { |
||||
|
||||
@Resource |
||||
private SysDictDataMapper sysDictDataMapper; |
||||
|
||||
@Resource |
||||
private CollectionParamsManageMapper collectionParamsManageMapper; |
||||
|
||||
@Resource |
||||
private ComprehensiveReportMapper comprehensiveReportMapper; |
||||
|
||||
@Override |
||||
public List<?> report(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 isSingleTable = "month".equalsIgnoreCase(timeType) || "year".equalsIgnoreCase(timeType); |
||||
if (!isSingleTable) { |
||||
lastTableName.set(lastTableName + vo.getStartTime().substring(0, 4)); |
||||
curTableName.set(curTableName + vo.getEndTime().substring(0, 4)); |
||||
} |
||||
|
||||
// 查询系统类型数据
|
||||
List<SysDictData> sysTypeData = sysDictDataMapper.selectDictDataByType("sys_type"); |
||||
// 定义参数类型
|
||||
String[] paramTypes = {"16", "17", "18", "19"}; |
||||
// 初始化结果列表
|
||||
List<OverviewEnergyDTO> result = new ArrayList<>(); |
||||
// 使用Map存储不同类型的能源DTO
|
||||
Map<String, OverviewEnergyDTO> energyMap = new HashMap<>(); |
||||
energyMap.put("16", new OverviewEnergyDTO()); |
||||
energyMap.put("17", new OverviewEnergyDTO()); |
||||
energyMap.put("18", new OverviewEnergyDTO()); |
||||
energyMap.put("19", new OverviewEnergyDTO()); |
||||
|
||||
for (String paramType : paramTypes) { |
||||
List<ColumnFilter> dataList = new ArrayList<>(); |
||||
for (SysDictData sysDictData : sysTypeData) { |
||||
String sysType = sysDictData.getDictValue(); |
||||
// 查询采集参数
|
||||
List<CollectionParamsManage> collectionParamsManages = queryCollectionParams(paramType, sysType, 40, null, false); |
||||
// 合并数据
|
||||
if (collectionParamsManages != null && !collectionParamsManages.isEmpty()) { |
||||
// 判断两个表是否一样
|
||||
boolean isSameTable = lastTableName.get().equals(curTableName.get()); |
||||
if (isSameTable) { |
||||
List<ColumnFilter> columnFilters = comprehensiveReportMapper.energyAnalysisOneTable(collectionParamsManages, |
||||
lastTableName.get(), |
||||
curTableName.get(), |
||||
DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", vo.getStartTime()), |
||||
DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", vo.getEndTime()), |
||||
timeType); |
||||
dataList.addAll(columnFilters); |
||||
} else { |
||||
// 两个表不一样
|
||||
List<ColumnFilter> columnFilters = comprehensiveReportMapper.energyAnalysisManyTable(collectionParamsManages, |
||||
lastTableName.get(), |
||||
curTableName.get(), |
||||
DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", vo.getStartTime()), |
||||
DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", vo.getEndTime()), |
||||
timeType); |
||||
dataList.addAll(columnFilters); |
||||
} |
||||
} |
||||
} |
||||
// 初始化能源数据
|
||||
initialEnergyData(dataList, energyMap.get(paramType), getEnergyLabel(paramType), getEnergyUnit(paramType), result); |
||||
|
||||
} |
||||
return result.isEmpty() ? List.of() : result; |
||||
} |
||||
|
||||
private List<CollectionParamsManage> queryCollectionParams(String paramType, String sysType, int grade, String terminalDeviceType, boolean isNow) { |
||||
QueryWrapper<CollectionParamsManage> queryWrapper = new QueryWrapper<>(); |
||||
LocalDate today = LocalDate.now(); |
||||
String todayStr = today.toString(); // 格式为 'YYYY-MM-DD'
|
||||
queryWrapper.eq("param_type", paramType) |
||||
.eq("system_type", sysType) |
||||
.eq("grade", grade); |
||||
if (isNow) { |
||||
queryWrapper.apply("DATE(cur_time) = DATE({0})", todayStr); |
||||
} |
||||
|
||||
|
||||
if (terminalDeviceType != null && !terminalDeviceType.isEmpty()) { |
||||
queryWrapper.eq("terminal_device_type", terminalDeviceType); |
||||
} |
||||
|
||||
// 先查询总表
|
||||
queryWrapper.eq("mt_is_sum", 0); |
||||
Long count = collectionParamsManageMapper.selectCount(queryWrapper); |
||||
if (count > 0) { |
||||
return collectionParamsManageMapper.selectList(queryWrapper); |
||||
} |
||||
|
||||
// 查询分表
|
||||
queryWrapper = new QueryWrapper<>(); |
||||
queryWrapper.eq("param_type", paramType) |
||||
.eq("system_type", sysType) |
||||
.eq("grade", grade); |
||||
if (isNow) { |
||||
queryWrapper.apply("DATE(cur_time) = DATE({0})", todayStr); |
||||
} |
||||
|
||||
// if (terminalDeviceType != null && !terminalDeviceType.isEmpty()) {
|
||||
// queryWrapper.eq("terminal_device_type", terminalDeviceType);
|
||||
// }
|
||||
return collectionParamsManageMapper.selectList(queryWrapper); |
||||
} |
||||
|
||||
private String getEnergyLabel(String paramType) { |
||||
switch (paramType) { |
||||
case "16": |
||||
return "总用电量"; |
||||
case "17": |
||||
return "总产冷量"; |
||||
case "18": |
||||
return "总用水量"; |
||||
case "19": |
||||
return "总用气量"; |
||||
default: |
||||
throw new IllegalArgumentException("Invalid param type: " + paramType); |
||||
} |
||||
} |
||||
|
||||
private String getEnergyUnit(String paramType) { |
||||
switch (paramType) { |
||||
case "16": |
||||
return "kw/h"; |
||||
case "17": |
||||
return "kw"; |
||||
case "18": |
||||
return "t"; |
||||
case "19": |
||||
return "t"; |
||||
default: |
||||
throw new IllegalArgumentException("Invalid param type: " + paramType); |
||||
} |
||||
} |
||||
|
||||
|
||||
private static void initialEnergyData(List<ColumnFilter> dataList, |
||||
OverviewEnergyDTO ele, |
||||
String paramTypeName, |
||||
String unitName, |
||||
List<OverviewEnergyDTO> result) { |
||||
if (!dataList.isEmpty()) { |
||||
// 根据时间分组,求和取总和,再根据时间升序排序
|
||||
// 使用LinkedHashMap保持时间顺序
|
||||
LinkedHashMap<String, Double> eleMap = dataList.stream() |
||||
.sorted(Comparator.comparing(ColumnFilter::getName)) // 按时间字段排序
|
||||
.collect(Collectors.groupingBy( |
||||
ColumnFilter::getName, |
||||
LinkedHashMap::new, |
||||
Collectors.summingDouble(value -> |
||||
new BigDecimal(value.getValue()).doubleValue()) |
||||
)); |
||||
|
||||
// 提取时间序列和数值序列
|
||||
String[] timeArray = eleMap.keySet().toArray(new String[0]); |
||||
String[] valueArray = eleMap.values().stream() |
||||
.map(d -> String.format("%.2f", d)) // 保留两位小数
|
||||
.toArray(String[]::new); |
||||
|
||||
// 设置到对象中
|
||||
ele.setName(paramTypeName); |
||||
ele.setUnit(unitName); |
||||
ele.setTimeStr(timeArray); |
||||
ele.setData(valueArray); |
||||
result.add(ele); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue