Browse Source

1、每日抄表记录报表、热水热泵运行报表添加。

dev_mz
25604 2 weeks ago
parent
commit
22ce82f641
  1. BIN
      doc/节能改造每日能耗统计表.xlsx
  2. 141
      mh-admin/src/main/java/com/mh/web/controller/report/ReportHotWaterController.java
  3. 131
      mh-admin/src/main/java/com/mh/web/controller/report/ReportMeterReadingsController.java
  4. 2
      mh-admin/src/main/resources/application.yml
  5. BIN
      mh-admin/src/main/resources/节能岛改造每日能耗统计表.xlsx
  6. 18
      mh-admin/src/test/java/com/mh/MHApplicationTest.java
  7. 170
      mh-common/src/main/java/com/mh/common/core/domain/dto/BFloorReportHotWaterDTO.java
  8. 210
      mh-common/src/main/java/com/mh/common/core/domain/dto/ThreeFloorReportHotWaterDTO.java
  9. 224
      mh-common/src/main/java/com/mh/common/core/domain/entity/ReportHotWaterParamHis.java
  10. 114
      mh-common/src/main/java/com/mh/common/core/domain/entity/ReportMeterReadingsHis.java
  11. 52
      mh-quartz/src/main/java/com/mh/quartz/task/ReportTask.java
  12. 35
      mh-system/src/main/java/com/mh/system/mapper/report/ReportHotWaterParamHisMapper.java
  13. 49
      mh-system/src/main/java/com/mh/system/mapper/report/ReportMeterReadingsHisMapper.java
  14. 20
      mh-system/src/main/java/com/mh/system/service/report/IMeterReadingsHisService.java
  15. 22
      mh-system/src/main/java/com/mh/system/service/report/IReportHotWaterService.java
  16. 300
      mh-system/src/main/java/com/mh/system/service/report/impl/MeterReadingsHisServiceImpl.java
  17. 121
      mh-system/src/main/java/com/mh/system/service/report/impl/ReportHotWaterServiceImpl.java
  18. 133
      sql/2025新增.sql
  19. 281
      sql/创建热水运行报表存储过程20251023.sql

BIN
doc/节能改造每日能耗统计表.xlsx

Binary file not shown.

141
mh-admin/src/main/java/com/mh/web/controller/report/ReportHotWaterController.java

@ -0,0 +1,141 @@
package com.mh.web.controller.report;
import com.alibaba.excel.EasyExcel;
import com.mh.common.core.controller.BaseController;
import com.mh.common.core.domain.AjaxResult;
import com.mh.common.core.domain.dto.BFloorReportHotWaterDTO;
import com.mh.common.core.domain.dto.ThreeFloorReportHotWaterDTO;
import com.mh.common.core.domain.entity.ReportHotWaterParamHis;
import com.mh.common.core.domain.entity.ReportSysRunParamHis;
import com.mh.common.core.page.TableDataInfo;
import com.mh.common.utils.StringUtils;
import com.mh.common.utils.file.handle.ExcelFillCellMergeHandler;
import com.mh.common.utils.file.handle.ReportSysParamHandler;
import com.mh.common.utils.file.handle.RowHeightStyleHandler;
import com.mh.system.service.report.IReportHotWaterService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author LJF
* @version 1.0
* @project NewZhujiang_Server
* @description 热泵系统运行参数报表
* @date 2024-05-30 08:45:57
*/
@RestController
@RequestMapping("/reportHotWater")
@Slf4j
public class ReportHotWaterController extends BaseController {
private final IReportHotWaterService reportHotWaterService;
private ReportHotWaterController(IReportHotWaterService reportHotWaterService) {
this.reportHotWaterService = reportHotWaterService;
}
@PostMapping("/list")
public TableDataInfo list(@RequestBody ReportHotWaterParamHis reportHotWaterParamHis)
{
startPage();
List<ReportHotWaterParamHis> list = reportHotWaterService.selectList(reportHotWaterParamHis);
return getDataTable(list);
}
@PutMapping("/edit")
public AjaxResult edit(@RequestBody ReportHotWaterParamHis reportHotWaterParamHis)
{
return toAjax(reportHotWaterService.updateRunParams(reportHotWaterParamHis));
}
@PostMapping("/export")
public void exportExcel(@RequestBody ReportHotWaterParamHis reportHotWaterParamHis, HttpServletResponse response) {
// 文件名
try {
String fileName = "热水热泵运行记录表.xlsx";
String floorId = reportHotWaterParamHis.getFloorId();
String headTitle = "热水热泵运行记录表";
if (!StringUtils.isBlank(floorId)) {
if (floorId.contains("-1楼")) {
fileName = "-1楼热水热泵运行记录表.xlsx";
headTitle = "-1楼热水热泵运行记录表";
} else {
fileName = "3楼热水热泵运行记录表.xlsx";
headTitle = "3楼热水热泵运行记录表";
}
}
// 从数据库获取数据
List<ReportHotWaterParamHis> list = reportHotWaterService.selectList(reportHotWaterParamHis);
if (list != null) {
// 设置响应格式
response.setContentType("application/vdn.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
response.setCharacterEncoding("UTF-8");
ExcelFillCellMergeHandler mergePrevCol = new ExcelFillCellMergeHandler();
int headSize = 3;
if (floorId.contains("-1楼")) {
List<BFloorReportHotWaterDTO> infoDTOS = list.stream().map(info -> {
BFloorReportHotWaterDTO deviceInfoDTO = new BFloorReportHotWaterDTO();
BeanUtils.copyProperties(info, deviceInfoDTO);
// 单独处理启停和运行状态
deviceInfoDTO.setStatusRunHotPumpOneStr(info.getStatusRunHotPumpOne() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusSwitchHotPumpOneStr(info.getStatusSwitchHotPumpOne() == 1 ? "开机" : "关机");
deviceInfoDTO.setStatusRunHotPumpTwoStr(info.getStatusRunHotPumpTwo() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusSwitchHotPumpTwoStr(info.getStatusSwitchHotPumpTwo() == 1 ? "开机" : "关机");
deviceInfoDTO.setStatusRunSupplyPumpOneStr(info.getStatusRunSupplyPumpOne() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusRunSupplyPumpTwoStr(info.getStatusRunSupplyPumpTwo() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusRunSupplyPumpThreeStr(info.getStatusRunSupplyPumpThree() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusRunSupplyPumpFourStr(info.getStatusRunSupplyPumpFour() == 1 ? "运行" : "不运行");
return deviceInfoDTO;
}).collect(Collectors.toList());
// 内容格式
EasyExcel.write(response.getOutputStream(), BFloorReportHotWaterDTO.class)
.registerWriteHandler(new ReportSysParamHandler(headTitle))
.registerWriteHandler(mergePrevCol)
.registerWriteHandler(new RowHeightStyleHandler())
.sheet(fileName.replace(".xlsx", ""))
.doWrite(infoDTOS);
} else {
List<ThreeFloorReportHotWaterDTO> infoDTOS = list.stream().map(info -> {
ThreeFloorReportHotWaterDTO deviceInfoDTO = new ThreeFloorReportHotWaterDTO();
BeanUtils.copyProperties(info, deviceInfoDTO);
// 单独处理启停和运行状态
deviceInfoDTO.setStatusRunHotPumpOneStr(info.getStatusRunHotPumpOne() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusSwitchHotPumpOneStr(info.getStatusSwitchHotPumpOne() == 1 ? "开机" : "关机");
deviceInfoDTO.setStatusRunHotPumpTwoStr(info.getStatusRunHotPumpTwo() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusSwitchHotPumpTwoStr(info.getStatusSwitchHotPumpTwo() == 1 ? "开机" : "关机");
deviceInfoDTO.setStatusRunHotPumpThreeStr(info.getStatusRunHotPumpThree() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusSwitchHotPumpThreeStr(info.getStatusSwitchHotPumpThree() == 1 ? "开机" : "关机");
deviceInfoDTO.setStatusRunHotPumpFourStr(info.getStatusRunHotPumpFour() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusSwitchHotPumpFourStr(info.getStatusSwitchHotPumpFour() == 1 ? "开机" : "关机");
deviceInfoDTO.setStatusRunSupplyPumpOneStr(info.getStatusRunSupplyPumpOne() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusRunSupplyPumpTwoStr(info.getStatusRunSupplyPumpTwo() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusRunSupplyPumpThreeStr(info.getStatusRunSupplyPumpThree() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusRunSupplyPumpFourStr(info.getStatusRunSupplyPumpFour() == 1 ? "运行" : "不运行");
return deviceInfoDTO;
}).collect(Collectors.toList());
// 内容格式
EasyExcel.write(response.getOutputStream(), ThreeFloorReportHotWaterDTO.class)
.registerWriteHandler(new ReportSysParamHandler(headTitle))
.registerWriteHandler(mergePrevCol)
.registerWriteHandler(new RowHeightStyleHandler())
.sheet(fileName.replace(".xlsx", ""))
.doWrite(infoDTOS);
}
}
} catch (IOException e) {
throw new RuntimeException("下载报表异常");
}
}
}

131
mh-admin/src/main/java/com/mh/web/controller/report/ReportMeterReadingsController.java

@ -0,0 +1,131 @@
package com.mh.web.controller.report;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.mh.common.core.controller.BaseController;
import com.mh.common.core.domain.dto.WeatherDataDTO;
import com.mh.common.core.domain.entity.ReportMeterReadingsHis;
import com.mh.common.core.page.TableDataInfo;
import com.mh.common.utils.DateUtils;
import com.mh.system.service.device.ICoolingSystemMonitorService;
import com.mh.system.service.report.IMeterReadingsHisService;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.ss.usermodel.*;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.*;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 每日抄表记录查询
* @date 2025-10-21 16:04:09
*/
@RestController
@RequestMapping("/reportMeterReadings")
public class ReportMeterReadingsController extends BaseController {
private final IMeterReadingsHisService meterReadingsHisService;
private final ICoolingSystemMonitorService coolingSystemMonitorService;
public ReportMeterReadingsController(IMeterReadingsHisService meterReadingsHisService, ICoolingSystemMonitorService coolingSystemMonitorService) {
this.meterReadingsHisService = meterReadingsHisService;
this.coolingSystemMonitorService = coolingSystemMonitorService;
}
@PostMapping("/list")
public TableDataInfo list(@RequestBody ReportMeterReadingsHis todayTimestamp)
{
List<ReportMeterReadingsHis> list = meterReadingsHisService.selectList(todayTimestamp);
return getDataTable(list);
}
@PostMapping("/export")
public void exportExcel(@RequestBody ReportMeterReadingsHis reportMeterReadingsHis, HttpServletResponse response) {
// 文件名
try {
String fileName = "节能岛改造每日能耗统计表"+ DateUtils.dateToString(reportMeterReadingsHis.getTodayTimestamp(), "yyyyMMdd")+".xlsx";
// 读取资源文件
ClassPathResource classPathResource = new ClassPathResource(File.separator + "节能岛改造每日能耗统计表.xlsx");
// 获取数据
List<ReportMeterReadingsHis> list = meterReadingsHisService.selectList(reportMeterReadingsHis);
// 组织并填充模板数据
ByteArrayOutputStream byteArrayOutputStream = compositeFill(classPathResource.getInputStream(), reportMeterReadingsHis.getTodayTimestamp(), list);
// 设置响应格式
response.setContentType("application/vdn.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
response.setCharacterEncoding("UTF-8");
// 将文件内容写入响应输出流,浏览器可以直接触发下载
response.getOutputStream().write(byteArrayOutputStream.toByteArray());
response.getOutputStream().flush();
} catch (IOException e) {
throw new RuntimeException("下载报表异常");
}
}
private ByteArrayOutputStream compositeFill(InputStream templateInputStream, Date todayTimestamp, List<ReportMeterReadingsHis> list) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 使用EasyExcel的模板填充功能,在这里指定合并单元格,这里应该是easyExcel的bug,第一列无法合并,其他列都可以,所以第一列单独用原生poi进行合并
try (ExcelWriter excelWriter = EasyExcel.write(byteArrayOutputStream).withTemplate(templateInputStream)
.build()) {
WriteSheet writeSheet = EasyExcel.writerSheet().build();
// 防止上面两个表格覆盖下面两个表格,每一行都采用新增一行的方式
// FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
// 使用模板填充,必须使用FillWrapper,这是官方要求,并且每行两个表格只能有一个表格设置增行,否则会存在一个表格有空行,这里是造的测试数据
for (int i = 0; i < list.size(); i++) {
excelWriter.fill(new FillWrapper("data"+(i+1), List.of(list.get(i))), writeSheet);
}
// 设置表格外的填充数据,例如总计、日期等数据
HashMap<String, Object> map = new HashMap<>();
List<WeatherDataDTO> weatherTemp = (List<WeatherDataDTO>) coolingSystemMonitorService.getWeatherTemp(DateUtils.dateToString(todayTimestamp, "yyyy-MM-dd"), DateUtils.dateToString(todayTimestamp, "yyyy-MM-dd"));
if (!weatherTemp.isEmpty()) {
String maxTemp = weatherTemp.getFirst().getMaxTemp();
map.put("maxTemp", maxTemp);
String minTemp = weatherTemp.getFirst().getMinTemp();
map.put("minTemp", minTemp);
}
map.put("date", DateUtils.dateToString(todayTimestamp, "yyyy年MM月dd日"));
excelWriter.fill(map, writeSheet);
// 2. 获取 Workbook 并计算公式
Workbook workbook = excelWriter.writeContext()
.writeWorkbookHolder()
.getWorkbook();
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
for (Row row : workbook.getSheetAt(0)) {
for (Cell cell : row) {
if (cell.getCellType() == CellType.FORMULA) {
evaluator.evaluateFormulaCell(cell); // 单元格级计算
// evaluator.evaluateAll(); // 全工作簿计算(推荐)
}
}
}
// 3. 强制刷新计算结果
workbook.setForceFormulaRecalculation(true);
excelWriter.finish();
}
// 合并单元格,由于easyExcel自带的OnceAbsoluteMergeStrategy合并策略bug,这里需要用poi合并一下
return byteArrayOutputStream;
}
}

2
mh-admin/src/main/resources/application.yml

@ -1,6 +1,6 @@
spring: spring:
profiles: profiles:
active: dev active: prod
# 用户配置 # 用户配置
user: user:

BIN
mh-admin/src/main/resources/节能岛改造每日能耗统计表.xlsx

Binary file not shown.

18
mh-admin/src/test/java/com/mh/MHApplicationTest.java

@ -16,6 +16,8 @@ import com.mh.system.service.ISysParamsService;
import com.mh.system.service.ISysUserService; import com.mh.system.service.ISysUserService;
import com.mh.system.service.device.IDeviceQrManageService; import com.mh.system.service.device.IDeviceQrManageService;
import com.mh.system.service.operation.IAlarmRecordsService; import com.mh.system.service.operation.IAlarmRecordsService;
import com.mh.system.service.report.IMeterReadingsHisService;
import com.mh.system.service.report.IReportHotWaterService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.checkerframework.checker.units.qual.A; import org.checkerframework.checker.units.qual.A;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -48,6 +50,22 @@ public class MHApplicationTest {
@Autowired @Autowired
private IAlarmRecordsService alarmRecordsService; private IAlarmRecordsService alarmRecordsService;
@Autowired
private IMeterReadingsHisService meterReadingsHisService;
@Autowired
private IReportHotWaterService reportHotWaterService;
@Test
public void reportHotWater() {
reportHotWaterService.execProRunParamHis();
}
@Test
public void testExecProMeterReadingsHis() {
meterReadingsHisService.execProMeterReadingsHis("2025-10-22");
}
@Test @Test
public void createAlarmTask() { public void createAlarmTask() {
alarmRecordsService.insertOrUpdateAlarmRecord("e1a3034edw6a9b3a79a86332886b24896"); alarmRecordsService.insertOrUpdateAlarmRecord("e1a3034edw6a9b3a79a86332886b24896");

170
mh-common/src/main/java/com/mh/common/core/domain/dto/BFloorReportHotWaterDTO.java

@ -0,0 +1,170 @@
package com.mh.common.core.domain.dto;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.*;
import com.alibaba.excel.enums.poi.BorderStyleEnum;
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
//import java.math.String;
/**
* @author LJF
* @version 1.0
* @project NewZhujiang_Server
* @description 三楼热水系统参数报表
* @date 2024-05-30 11:00:12
*/
@Data
@NoArgsConstructor
@Accessors(chain = true)
@HeadRowHeight(25)
@HeadFontStyle(fontHeightInPoints = 14)
@ContentFontStyle(fontHeightInPoints = 13)
@ContentRowHeight(25)
@ContentStyle(
horizontalAlignment = HorizontalAlignmentEnum.CENTER,
borderBottom = BorderStyleEnum.THIN,
borderLeft = BorderStyleEnum.THIN,
borderRight = BorderStyleEnum.THIN,
borderTop = BorderStyleEnum.THIN
)
@ColumnWidth(10)
public class BFloorReportHotWaterDTO {
/**
* 当前时间
*/
@ColumnWidth(17)
@ExcelProperty(value = {"${deviceType}", "时间", "时间"}, index = 0)
private String curTime;
// /**
// * 班次
// */
// @ColumnWidth(10)
// @ExcelProperty(value = {"${deviceType}", "班次", "班次"}, index = 1)
// private String classes;
/**
* 设定温度
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "1号热泵", "设定温度℃"}, index = 1)
private BigDecimal tempSetHotPumpOne;
/**
* 实际温度
*/
@ExcelProperty(value = {"${deviceType}", "1号热泵", "实际温度℃"}, index = 2)
@ColumnWidth(10)
private BigDecimal tempRealHotPumpOne;
/**
* 设备开关机
*/
@ExcelProperty(value = {"${deviceType}", "1号热泵", "设备开关机"}, index = 3)
@ColumnWidth(10)
private String statusSwitchHotPumpOneStr;
/**
* 设备运行状态
*/
@ExcelProperty(value = {"${deviceType}", "1号热泵", "设备运行状态"}, index = 4)
@ColumnWidth(10)
private String statusRunHotPumpOneStr;
/**
* 设定温度
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "2号热泵", "设定温度℃"}, index = 5)
private BigDecimal tempSetHotPumpTwo;
/**
* 实际温度
*/
@ExcelProperty(value = {"${deviceType}", "2号热泵", "实际温度℃"}, index = 6)
@ColumnWidth(10)
private BigDecimal tempRealHotPumpTwo;
/**
* 设备开关机
*/
@ExcelProperty(value = {"${deviceType}", "2号热泵", "设备开关机"}, index = 7)
@ColumnWidth(10)
private String statusSwitchHotPumpTwoStr;
/**
* 设备运行状态
*/
@ExcelProperty(value = {"${deviceType}", "2号热泵", "设备运行状态"}, index = 8)
@ColumnWidth(10)
private String statusRunHotPumpTwoStr;
// 高区/裙楼设定压力(bar)
@ExcelProperty(value = {"${deviceType}", "裙楼变频泵", "设定压力bar"}, index = 9)
@ColumnWidth(10)
private BigDecimal presSetSupplyPumpAreaOne;
// 高区/裙楼实际压力(bar)
@ExcelProperty(value = {"${deviceType}", "裙楼变频泵", "实际压力bar"}, index = 10)
@ColumnWidth(10)
private BigDecimal presRealSupplyPumpAreaOne;
// 高区/裙楼1号泵运行状态
@ExcelProperty(value = {"${deviceType}", "裙楼变频泵", "1号泵运行状态"}, index = 11)
@ColumnWidth(10)
private String statusRunSupplyPumpOneStr;
// 高区/裙楼2号泵运行状态
@ExcelProperty(value = {"${deviceType}", "裙楼变频泵", "2号泵运行状态"}, index = 12)
@ColumnWidth(10)
private String statusRunSupplyPumpTwoStr;
// 中区/中厨设定压力(bar)
@ExcelProperty(value = {"${deviceType}", "中厨变频泵", "设定压力bar"}, index = 13)
@ColumnWidth(10)
private BigDecimal presSetSupplyPumpAreaTwo;
// 中区/中厨实际压力(bar)
@ExcelProperty(value = {"${deviceType}", "中厨变频泵", "实际压力bar"}, index = 14)
@ColumnWidth(10)
private BigDecimal presRealSupplyPumpAreaTwo;
// 中区/中厨1号泵运行状态
@ExcelProperty(value = {"${deviceType}", "中厨变频泵", "1号泵运行状态"}, index = 15)
@ColumnWidth(10)
private String statusRunSupplyPumpThreeStr;
// 中区/中厨2号泵运行状态
@ExcelProperty(value = {"${deviceType}", "中厨变频泵", "2号泵运行状态"}, index = 16)
@ColumnWidth(10)
private String statusRunSupplyPumpFourStr;
// 高区/裙楼液位(米)
@ExcelProperty(value = {"${deviceType}", "水箱液位", "裙楼液位%"}, index = 17)
@ColumnWidth(10)
private BigDecimal levelWaterTankOne;
// 中区/中厨液位(米)
@ExcelProperty(value = {"${deviceType}", "水箱液位", "中厨液位%"}, index = 18)
@ColumnWidth(10)
private BigDecimal levelWaterTankTwo;
// 巡查记录人
@ExcelProperty(value = {"${deviceType}", "巡查记录人", "巡查记录人"}, index = 19)
@ColumnWidth(20)
private String recorder;
// 备注信息
@ExcelProperty(value = {"${deviceType}", "备注", "备注"}, index = 20)
@ColumnWidth(20)
private String remark;
}

210
mh-common/src/main/java/com/mh/common/core/domain/dto/ThreeFloorReportHotWaterDTO.java

@ -0,0 +1,210 @@
package com.mh.common.core.domain.dto;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.*;
import com.alibaba.excel.enums.poi.BorderStyleEnum;
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
//import java.math.String;
/**
* @author LJF
* @version 1.0
* @project NewZhujiang_Server
* @description 三楼热水系统参数报表
* @date 2024-05-30 11:00:12
*/
@Data
@NoArgsConstructor
@Accessors(chain = true)
@HeadRowHeight(25)
@HeadFontStyle(fontHeightInPoints = 14)
@ContentFontStyle(fontHeightInPoints = 13)
@ContentRowHeight(25)
@ContentStyle(
horizontalAlignment = HorizontalAlignmentEnum.CENTER,
borderBottom = BorderStyleEnum.THIN,
borderLeft = BorderStyleEnum.THIN,
borderRight = BorderStyleEnum.THIN,
borderTop = BorderStyleEnum.THIN
)
@ColumnWidth(10)
public class ThreeFloorReportHotWaterDTO {
/**
* 当前时间
*/
@ColumnWidth(17)
@ExcelProperty(value = {"${deviceType}", "时间", "时间"}, index = 0)
private String curTime;
// /**
// * 班次
// */
// @ColumnWidth(10)
// @ExcelProperty(value = {"${deviceType}", "班次", "班次"}, index = 1)
// private String classes;
/**
* 设定温度
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "1号热泵", "设定温度℃"}, index = 1)
private BigDecimal tempSetHotPumpOne;
/**
* 实际温度
*/
@ExcelProperty(value = {"${deviceType}", "1号热泵", "实际温度℃"}, index = 2)
@ColumnWidth(10)
private BigDecimal tempRealHotPumpOne;
/**
* 设备开关机
*/
@ExcelProperty(value = {"${deviceType}", "1号热泵", "设备开关机"}, index = 3)
@ColumnWidth(10)
private String statusSwitchHotPumpOneStr;
/**
* 设备运行状态
*/
@ExcelProperty(value = {"${deviceType}", "1号热泵", "设备运行状态"}, index = 4)
@ColumnWidth(10)
private String statusRunHotPumpOneStr;
/**
* 设定温度
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "2号热泵", "设定温度℃"}, index = 5)
private BigDecimal tempSetHotPumpTwo;
/**
* 实际温度
*/
@ExcelProperty(value = {"${deviceType}", "2号热泵", "实际温度℃"}, index = 6)
@ColumnWidth(10)
private BigDecimal tempRealHotPumpTwo;
/**
* 设备开关机
*/
@ExcelProperty(value = {"${deviceType}", "2号热泵", "设备开关机"}, index = 7)
@ColumnWidth(10)
private String statusSwitchHotPumpTwoStr;
/**
* 设备运行状态
*/
@ExcelProperty(value = {"${deviceType}", "2号热泵", "设备运行状态"}, index = 8)
@ColumnWidth(10)
private String statusRunHotPumpTwoStr;
// 3号热泵设定温度(℃)
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "3号热泵", "设定温度℃"}, index = 9)
private BigDecimal tempSetHotPumpThree;
// 3号热泵实际温度(℃)
@ExcelProperty(value = {"${deviceType}", "3号热泵", "实际温度℃"}, index = 10)
@ColumnWidth(10)
private BigDecimal tempRealHotPumpThree;
// 3号热泵启停状态
@ExcelProperty(value = {"${deviceType}", "3号热泵", "设备开关机"}, index = 11)
@ColumnWidth(10)
private String statusSwitchHotPumpThreeStr;
// 3号热泵运行状态
@ExcelProperty(value = {"${deviceType}", "3号热泵", "设备运行状态"}, index = 12)
@ColumnWidth(10)
private String statusRunHotPumpThreeStr;
// 4号热泵设定温度(℃)
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "4号热泵", "设定温度℃"}, index = 13)
private BigDecimal tempSetHotPumpFour;
// 4号热泵实际温度(℃)
@ExcelProperty(value = {"${deviceType}", "4号热泵", "实际温度℃"}, index = 14)
@ColumnWidth(10)
private BigDecimal tempRealHotPumpFour;
// 4号热泵启停状态
@ExcelProperty(value = {"${deviceType}", "4号热泵", "设备开关机"}, index = 15)
@ColumnWidth(10)
private String statusSwitchHotPumpFourStr;
// 4号热泵运行状态
@ExcelProperty(value = {"${deviceType}", "4号热泵", "设备运行状态"}, index = 16)
@ColumnWidth(10)
private String statusRunHotPumpFourStr;
// 高区/高区设定压力(bar)
@ExcelProperty(value = {"${deviceType}", "高区变频泵", "设定压力bar"}, index = 17)
@ColumnWidth(10)
private BigDecimal presSetSupplyPumpAreaOne;
// 高区/高区实际压力(bar)
@ExcelProperty(value = {"${deviceType}", "高区变频泵", "实际压力bar"}, index = 18)
@ColumnWidth(10)
private BigDecimal presRealSupplyPumpAreaOne;
// 高区/高区1号泵运行状态
@ExcelProperty(value = {"${deviceType}", "高区变频泵", "1号泵运行状态"}, index = 19)
@ColumnWidth(10)
private String statusRunSupplyPumpOneStr;
// 高区/高区2号泵运行状态
@ExcelProperty(value = {"${deviceType}", "高区变频泵", "2号泵运行状态"}, index = 20)
@ColumnWidth(10)
private String statusRunSupplyPumpTwoStr;
// 中区/中区设定压力(bar)
@ExcelProperty(value = {"${deviceType}", "中区变频泵", "设定压力bar"}, index = 21)
@ColumnWidth(10)
private BigDecimal presSetSupplyPumpAreaTwo;
// 中区/中区实际压力(bar)
@ExcelProperty(value = {"${deviceType}", "中区变频泵", "实际压力bar"}, index = 22)
@ColumnWidth(10)
private BigDecimal presRealSupplyPumpAreaTwo;
// 中区/中区1号泵运行状态
@ExcelProperty(value = {"${deviceType}", "中区变频泵", "1号泵运行状态"}, index = 23)
@ColumnWidth(10)
private String statusRunSupplyPumpThreeStr;
// 中区/中区2号泵运行状态
@ExcelProperty(value = {"${deviceType}", "中区变频泵", "2号泵运行状态"}, index = 24)
@ColumnWidth(10)
private String statusRunSupplyPumpFourStr;
// 高区/高区液位(米)
@ExcelProperty(value = {"${deviceType}", "水箱液位", "高区液位%"}, index = 25)
@ColumnWidth(10)
private BigDecimal levelWaterTankOne;
// 中区/中区液位(米)
@ExcelProperty(value = {"${deviceType}", "水箱液位", "中区液位%"}, index = 26)
@ColumnWidth(10)
private BigDecimal levelWaterTankTwo;
// 巡查记录人
@ExcelProperty(value = {"${deviceType}", "巡查记录人", "巡查记录人"}, index = 27)
@ColumnWidth(20)
private String recorder;
// 备注信息
@ExcelProperty(value = {"${deviceType}", "备注", "备注"}, index = 28)
@ColumnWidth(20)
private String remark;
}

224
mh-common/src/main/java/com/mh/common/core/domain/entity/ReportHotWaterParamHis.java

@ -0,0 +1,224 @@
package com.mh.common.core.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.mh.common.core.domain.BaseEntity;
import lombok.Getter;
import lombok.Setter;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Map;
import java.util.StringJoiner;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 生活热水供水热泵运行情况
* @date 2025-10-22 17:40:03
*/
@Setter
@Getter
@TableName("report_hot_water_param_his")
public class ReportHotWaterParamHis extends BaseEntity implements Serializable {
// 主键
@Serial
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.ASSIGN_UUID)
private String id;
// 楼层ID
private String floorId;
// 记录日期
private LocalDate curDate;
// 记录时间(varchar格式)
private String curTime;
// 班次
private String classes;
// 1号热泵设定温度(℃)
private BigDecimal tempSetHotPumpOne;
// 1号热泵实际温度(℃)
private BigDecimal tempRealHotPumpOne;
// 1号热泵启停状态(0-关闭,1-开启)
private Integer statusSwitchHotPumpOne;
// 1号热泵运行状态(0-故障,1-正常)
private Integer statusRunHotPumpOne;
// 2号热泵设定温度(℃)
private BigDecimal tempSetHotPumpTwo;
// 2号热泵实际温度(℃)
private BigDecimal tempRealHotPumpTwo;
// 2号热泵启停状态
private Integer statusSwitchHotPumpTwo;
// 2号热泵运行状态
private Integer statusRunHotPumpTwo;
// 3号热泵设定温度(℃)
private BigDecimal tempSetHotPumpThree;
// 3号热泵实际温度(℃)
private BigDecimal tempRealHotPumpThree;
// 3号热泵启停状态
private Integer statusSwitchHotPumpThree;
// 3号热泵运行状态
private Integer statusRunHotPumpThree;
// 4号热泵设定温度(℃)
private BigDecimal tempSetHotPumpFour;
// 4号热泵实际温度(℃)
private BigDecimal tempRealHotPumpFour;
// 4号热泵启停状态
private Integer statusSwitchHotPumpFour;
// 4号热泵运行状态
private Integer statusRunHotPumpFour;
// 高区/裙楼设定压力(MPa)
private BigDecimal presSetSupplyPumpAreaOne;
// 高区/裙楼实际压力(MPa)
private BigDecimal presRealSupplyPumpAreaOne;
// 高区/裙楼1号泵运行状态
private Integer statusRunSupplyPumpOne;
// 高区/裙楼2号泵运行状态
private Integer statusRunSupplyPumpTwo;
// 中区/中厨设定压力(MPa)
private BigDecimal presSetSupplyPumpAreaTwo;
// 中区/中厨实际压力(MPa)
private BigDecimal presRealSupplyPumpAreaTwo;
// 中区/中厨1号泵运行状态
private Integer statusRunSupplyPumpThree;
// 中区/中厨2号泵运行状态
private Integer statusRunSupplyPumpFour;
// 高区/裙楼液位(米)
private BigDecimal levelWaterTankOne;
// 中区/中厨液位(米)
private BigDecimal levelWaterTankTwo;
// 巡查记录人
private String recorder;
// 备注信息
private String remark;
@JsonIgnore
@TableField(exist = false)
private String searchValue;
/**
* 请求参数
*/
@TableField(exist = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, Object> params;
/** 创建者 */
@JsonIgnore
@TableField(exist = false)
private String createBy;
/** 创建时间 */
@TableField(exist = false)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 更新者 */
@JsonIgnore
@TableField(exist = false)
private String updateBy;
/** 更新时间 */
@JsonIgnore
@TableField(exist = false)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
// 无参构造
public ReportHotWaterParamHis() {
}
// Getter/Setter 方法(此处省略,实际开发中建议使用 Lombok @Data)
// 业务方法示例:判断热泵1是否正常运行
public boolean isHotPump1Normal() {
return statusRunHotPumpOne != null && statusRunHotPumpOne == 1;
}
// 业务方法示例:获取当前压力差值(高区)
public BigDecimal getHighAreaPressureDiff() {
return presRealSupplyPumpAreaOne.subtract(presSetSupplyPumpAreaOne);
}
@Override
public String toString() {
return new StringJoiner(", ", ReportHotWaterParamHis.class.getSimpleName() + "[", "]")
.add("id='" + id + "'")
.add("floorId='" + floorId + "'")
.add("curDate=" + curDate)
.add("curTime='" + curTime + "'")
.add("classes='" + classes + "'")
.add("tempSetHotPumpOne=" + tempSetHotPumpOne)
.add("tempRealHotPumpOne=" + tempRealHotPumpOne)
.add("statusSwitchHotPumpOne=" + statusSwitchHotPumpOne)
.add("statusRunHotPumpOne=" + statusRunHotPumpOne)
.add("tempSetHotPumpTwo=" + tempSetHotPumpTwo)
.add("tempRealHotPumpTwo=" + tempRealHotPumpTwo)
.add("statusSwitchHotPumpTwo=" + statusSwitchHotPumpTwo)
.add("statusRunHotPumpTwo=" + statusRunHotPumpTwo)
.add("tempSetHotPumpThree=" + tempSetHotPumpThree)
.add("tempRealHotPumpThree=" + tempRealHotPumpThree)
.add("statusSwitchHotPumpThree=" + statusSwitchHotPumpThree)
.add("statusRunHotPumpThree=" + statusRunHotPumpThree)
.add("tempSetHotPumpFour=" + tempSetHotPumpFour)
.add("tempRealHotPumpFour=" + tempRealHotPumpFour)
.add("statusSwitchHotPumpFour=" + statusSwitchHotPumpFour)
.add("statusRunHotPumpFour=" + statusRunHotPumpFour)
.add("presSetSupplyPumpAreaOne=" + presSetSupplyPumpAreaOne)
.add("presRealSupplyPumpAreaOne=" + presRealSupplyPumpAreaOne)
.add("statusRunSupplyPumpOne=" + statusRunSupplyPumpOne)
.add("statusRunSupplyPumpTwo=" + statusRunSupplyPumpTwo)
.add("presSetSupplyPumpAreaTwo=" + presSetSupplyPumpAreaTwo)
.add("presRealSupplyPumpAreaTwo=" + presRealSupplyPumpAreaTwo)
.add("statusRunSupplyPumpThree=" + statusRunSupplyPumpThree)
.add("statusRunSupplyPumpFour=" + statusRunSupplyPumpFour)
.add("levelWaterTankOne=" + levelWaterTankOne)
.add("levelWaterTankTwo=" + levelWaterTankTwo)
.add("recorder='" + recorder + "'")
.add("remark='" + remark + "'")
.toString();
}
}

114
mh-common/src/main/java/com/mh/common/core/domain/entity/ReportMeterReadingsHis.java

@ -0,0 +1,114 @@
package com.mh.common.core.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
import java.util.Date;
import java.util.StringJoiner;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 设备抄表记录表
* @date 2025-10-21 10:26:12
*/
@Setter
@Getter
public class ReportMeterReadingsHis {
@TableId(value = "id", type = IdType.ASSIGN_UUID)
private String id;
/**
* 设备类型
*/
private String mtType;
/**
* 设备位置
*/
private String location;
/**
* 设备编号
*/
private String mtNum;
/**
* 昨日抄表读数
*/
private BigDecimal yesterdayReading;
/**
* 昨日抄表时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date yesterdayTimestamp;
/**
* 当日抄表读数
*/
private BigDecimal todayReading;
/**
* 当日抄表时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date todayTimestamp;
/**
* 设备倍率
*/
private int mtRatio;
/**
* 当日总读数*设备倍率
*/
private BigDecimal total;
/**
* 当日单价
*/
private BigDecimal unitPrice;
/**
* 当日金额
*/
private BigDecimal cost;
/**
* 记录创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 排序序号
*/
private int sortOrder;
@Override
public String toString() {
return new StringJoiner(", ", ReportMeterReadingsHis.class.getSimpleName() + "[", "]")
.add("id='" + id + "'")
.add("mtType='" + mtType + "'")
.add("location='" + location + "'")
.add("mtNum='" + mtNum + "'")
.add("yesterdayReading=" + yesterdayReading)
.add("yesterdayTimestamp=" + yesterdayTimestamp)
.add("todayReading=" + todayReading)
.add("todayTimestamp=" + todayTimestamp)
.add("mtRatio=" + mtRatio)
.add("total=" + total)
.add("unitPrice=" + unitPrice)
.add("cost=" + cost)
.add("createTime=" + createTime)
.add("sortOrder=" + sortOrder)
.toString();
}
}

52
mh-quartz/src/main/java/com/mh/quartz/task/ReportTask.java

@ -0,0 +1,52 @@
package com.mh.quartz.task;
import com.mh.common.utils.DateUtils;
import com.mh.common.utils.StringUtils;
import com.mh.system.service.report.IMeterReadingsHisService;
import com.mh.system.service.report.IReportHotWaterService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Calendar;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 报表定时记录生成
* @date 2025-10-22 10:39:00
*/
@Slf4j
@Component("reportTask")
public class ReportTask {
@Autowired
private IMeterReadingsHisService meterReadingsHisService;
@Autowired
private IReportHotWaterService reportHotWaterService;
/**
* 创建抄表记录查询
*/
public void createMeterReadingHis(String curDate) {
// 获取当前时间的前一天
if (StringUtils.isEmpty(curDate)) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_YEAR, -1);
curDate = DateUtils.dateToString(calendar.getTime(), DateUtils.YYYY_MM_DD);
}
// 定时执行运行脚本
meterReadingsHisService.execProMeterReadingsHis(curDate);
}
/**
* 创建热水热泵运行参数
*/
public void createHotWaterRunParam() {
// 定时执行运行脚本
reportHotWaterService.execProRunParamHis();
}
}

35
mh-system/src/main/java/com/mh/system/mapper/report/ReportHotWaterParamHisMapper.java

@ -0,0 +1,35 @@
package com.mh.system.mapper.report;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mh.common.core.domain.entity.ReportHotWaterParamHis;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.StatementType;
import java.util.List;
/**
* @author LJF
* @version 1.0
* @project NewZhujiang_Server
* @description 热水运行参数服务类
* @date 2024-05-29 11:23:32
*/
@Mapper
public interface ReportHotWaterParamHisMapper extends BaseMapper<ReportHotWaterParamHis> {
@Select("call pro_hot_water_run_param(#{floorId,jdbcType=VARCHAR,mode=IN}, #{floorId1,jdbcType=VARCHAR,mode=IN}, #{floorId2,jdbcType=VARCHAR,mode=IN}, #{curTime,jdbcType=VARCHAR,mode=IN})")
@Options(statementType = StatementType.CALLABLE)
void execProHotWaterRunParam(@Param("floorId") String floorId,
@Param("floorId1") String floorId1,
@Param("floorId2") String floorId2,
@Param("curTime") String curTime);
@Select("select * from report_hot_water_param_his where floor_id = #{floorId} " +
" and cur_time >= #{beginDate} and cur_time <= #{endDate} order by cur_time desc ")
List<ReportHotWaterParamHis> findPage(@Param("floorId") String floorId,
@Param("beginDate") String beginDate,
@Param("endDate") String endDate);
}

49
mh-system/src/main/java/com/mh/system/mapper/report/ReportMeterReadingsHisMapper.java

@ -0,0 +1,49 @@
package com.mh.system.mapper.report;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mh.common.core.domain.entity.ReportMeterReadingsHis;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 抄表记录mapper类
* @date 2025-10-21 16:15:45
*/
@Mapper
public interface ReportMeterReadingsHisMapper extends BaseMapper<ReportMeterReadingsHis> {
@Select("select * from report_meter_readings_his where today_timestamp = #{curDate}::timestamp order by sort_order ")
List<ReportMeterReadingsHis> selectListByDate(@Param("curDate") String curDate);
@Select("select " +
" sdd.dict_label as mt_type, " +
" cpm.remark as location, " +
" cpm.mt_num, " +
" dd.\"last_value\" as yesterday_reading, " +
" dd.last_time as yesterday_timestamp, " +
" dd.cur_value as today_reading, " +
" dd.cur_time as today_timestamp, " +
" dd.ratio as mt_ratio, " +
" cpm.price as unit_price " +
"from " +
" collection_params_manage cpm " +
"join ${tableName} dd on " +
" cpm.mt_num = dd.device_num " +
"join sys_dict_data sdd on " +
" cpm.mt_type = sdd.dict_value " +
"where " +
" sdd.dict_type = 'sys_mt_type' " +
" and cpm.grade = '40' " +
" and dd.cur_time = #{curDate}::timestamp ")
List<ReportMeterReadingsHis> selectRecordListByDate(String tableName, String curDate);
@Delete("delete from report_meter_readings_his where today_timestamp = #{curDate}::timestamp")
void deleteByDate(@ Param("curDate") String curDate);
}

20
mh-system/src/main/java/com/mh/system/service/report/IMeterReadingsHisService.java

@ -0,0 +1,20 @@
package com.mh.system.service.report;
import com.mh.common.core.domain.entity.ReportMeterReadingsHis;
import java.util.List;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 设备抄表服务类
* @date 2025-10-21 16:07:35
*/
public interface IMeterReadingsHisService {
void execProMeterReadingsHis(String curDate);
List<ReportMeterReadingsHis> selectList(ReportMeterReadingsHis todayTimestamp);
}

22
mh-system/src/main/java/com/mh/system/service/report/IReportHotWaterService.java

@ -0,0 +1,22 @@
package com.mh.system.service.report;
import com.mh.common.core.domain.entity.ReportHotWaterParamHis;
import com.mh.common.core.domain.entity.ReportSysRunParamHis;
import java.util.List;
/**
* @author LJF
* @version 1.0
* @project NewZhujiang_Server
* @description 报表服务类
* @date 2024-05-29 11:20:30
*/
public interface IReportHotWaterService {
void execProRunParamHis();
List<ReportHotWaterParamHis> selectList(ReportHotWaterParamHis reportHotWaterParamHis);
int updateRunParams(ReportHotWaterParamHis reportHotWaterParamHis);
}

300
mh-system/src/main/java/com/mh/system/service/report/impl/MeterReadingsHisServiceImpl.java

@ -0,0 +1,300 @@
package com.mh.system.service.report.impl;
import com.mh.common.core.domain.entity.ReportMeterReadingsHis;
import com.mh.common.utils.DateUtils;
import com.mh.common.utils.StringUtils;
import com.mh.system.mapper.report.ReportMeterReadingsHisMapper;
import com.mh.system.service.report.IMeterReadingsHisService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 设备抄表服务类
* @date 2025-10-21 16:09:08
*/
@Slf4j
@Service
public class MeterReadingsHisServiceImpl implements IMeterReadingsHisService {
@Resource
private ReportMeterReadingsHisMapper reportMeterReadingsHisMapper;
private final List<String> locationList = List.of(
"磁悬浮3号空调主机",
"变频5号冷冻泵",
"4号冷冻泵",
"变频5号冷却泵",
"4号冷却泵",
"变频1号冷却塔",
"变频2号冷却塔",
"变频3号冷却塔",
"空调系统用电总合计:",
"三楼热泵控制柜",
"三楼变频水泵控制柜",
"洗衣房热泵控制柜",
"群楼中厨水泵控制柜",
"热水热泵系统用电总合计:",
"空调冷冻水",
"空调冷却水",
"三楼中、高区热水",
"群楼、中厨房热水",
"热水热泵系统用水总合计:",
"蒸汽发生器+采暖",
"蒸汽发生器+采暖",
"蒸汽发生器+采暖用气总合计:",
"蒸汽发生器+采暖",
"蒸汽发生器+采暖用电总合计:",
"蒸汽发生器+采暖",
"蒸汽发生器用水总合计:",
"水、电、气费用总合计(水/电/气价预估单价,单价需以实际缴费为准):",
"中央空调冷冻流量",
"中央空调冷却流量",
"中央空调采暖流量",
"蒸汽流量"
);
private final List<String> mtTypeList = List.of(
"电表",
"电表",
"电表",
"电表",
"电表",
"电表",
"电表",
"电表",
"电表",
"电表",
"电表",
"电表",
"电表",
"电表",
"水表",
"水表",
"水表",
"水表",
"水表",
"燃气表(常用)",
"燃气表(备用)",
"燃气表",
"电表",
"电表",
"水表",
"水表",
"总合计",
"流量计量表",
"流量计量表",
"流量计量表",
"流量计量表"
);
@Override
public void execProMeterReadingsHis(String curDate) {
// 根据时间查询对应的每日的采集抄表记录
String tableName = "data_day" + StringUtils.substring(curDate, 0, 4);
List<ReportMeterReadingsHis> list = reportMeterReadingsHisMapper.selectRecordListByDate(tableName, curDate);
if (null == list) {
return;
}
reportMeterReadingsHisMapper.deleteByDate(curDate + " 00:00:00");
// 循环处理数据
List<ReportMeterReadingsHis> filteredList = processLocationMatching(list, curDate);
list = filteredList;
// 对list进行排序
list.sort(Comparator.comparingInt(ReportMeterReadingsHis::getSortOrder));
// 处理数据库操作
list = handleDatabaseOperations(list, curDate);
// 创建合计对象
createAggregateObjects(list, curDate);
// 最终插入操作
performFinalInsert(list, curDate);
}
private List<ReportMeterReadingsHis> processLocationMatching(List<ReportMeterReadingsHis> originalList, String curDate) {
List<ReportMeterReadingsHis> filteredList = new ArrayList<>();
for (int i = 0; i < locationList.size(); i++) {
int finalI = i;
Optional<ReportMeterReadingsHis> matchedRecord = originalList.stream()
.filter(meterReadingsHis -> meterReadingsHis != null
&& meterReadingsHis.getLocation() != null
&& meterReadingsHis.getLocation().equals(locationList.get(finalI)))
.findFirst();
if (matchedRecord.isPresent()) {
ReportMeterReadingsHis reportMeterReadingsHis = matchedRecord.get();
normalizeMtType(reportMeterReadingsHis);
reportMeterReadingsHis.setSortOrder(i + 1);
filteredList.add(reportMeterReadingsHis);
} else if (!locationList.get(i).contains("合计")) {
// 没有对应的数据就生成对象
ReportMeterReadingsHis reportMeterReadingsHis = new ReportMeterReadingsHis();
reportMeterReadingsHis.setMtType(mtTypeList.get(i));
reportMeterReadingsHis.setLocation(locationList.get(i));
reportMeterReadingsHis.setYesterdayReading(new BigDecimal("0"));
reportMeterReadingsHis.setTodayReading(new BigDecimal("0"));
reportMeterReadingsHis.setTodayTimestamp(DateUtils.parseDate(curDate + " 00:00:00"));
reportMeterReadingsHis.setUnitPrice(new BigDecimal("1"));
reportMeterReadingsHis.setSortOrder(i + 1);
filteredList.add(reportMeterReadingsHis);
}
}
return filteredList;
}
private void normalizeMtType(ReportMeterReadingsHis reportMeterReadingsHis) {
if (reportMeterReadingsHis.getMtType() != null) {
if (reportMeterReadingsHis.getMtType().contains("电表")) {
reportMeterReadingsHis.setMtType("电表");
} else if (reportMeterReadingsHis.getMtType().contains("水表")) {
reportMeterReadingsHis.setMtType("水表");
} else if (reportMeterReadingsHis.getMtType().contains("冷量计")) {
reportMeterReadingsHis.setMtType("流量计量表");
}
}
}
private List<ReportMeterReadingsHis> handleDatabaseOperations(List<ReportMeterReadingsHis> list, String curDate) {
List<ReportMeterReadingsHis> oldList = reportMeterReadingsHisMapper.selectListByDate(curDate + " 00:00:00");
if (oldList == null || oldList.isEmpty()) {
reportMeterReadingsHisMapper.insert(list);
list = reportMeterReadingsHisMapper.selectListByDate(curDate + " 00:00:00");
} else {
list = oldList;
}
return list;
}
private void createAggregateObjects(List<ReportMeterReadingsHis> list, String curDate) {
Map<Integer, Function<List<ReportMeterReadingsHis>, ReportMeterReadingsHis>> aggregateCreators = Map.of(
8, l -> createAggregateObject("电表", "空调系统用电总合计:",
calculateTotalByRange(l, 0, 9), Objects.requireNonNull(list.stream().filter(v -> v.getSortOrder() == 8).findFirst().orElse(null))),
13, l -> createAggregateObject("电表", "热水热泵系统用电总合计:",
calculateTotalByRange(l, 9, 14), Objects.requireNonNull(list.stream().filter(v -> v.getSortOrder() == 13).findFirst().orElse(null))),
18, l -> createAggregateObject("水表", "热水热泵系统用水总合计:",
calculateTotalByRange(l, 14, 19), Objects.requireNonNull(list.stream().filter(v -> v.getSortOrder() == 18).findFirst().orElse(null))),
21, l -> createAggregateObject("燃气表", "蒸汽发生器+采暖用气总合计:",
calculateTotalByRange(l, 19, 22), Objects.requireNonNull(list.stream().filter(v -> v.getSortOrder() == 21).findFirst().orElse(null))),
23, l -> createAggregateObject("电表", "蒸汽发生器+采暖用电总合计:",
calculateTotalByRange(l, 22, 24), Objects.requireNonNull(list.stream().filter(v -> v.getSortOrder() == 23).findFirst().orElse(null))),
25, l -> createAggregateObject("水表", "蒸汽发生器用水总合计:",
calculateTotalByRange(l, 24, 26), Objects.requireNonNull(list.stream().filter(v -> v.getSortOrder() == 25).findFirst().orElse(null)))
);
for (int i = 0; i < locationList.size(); i++) {
if (aggregateCreators.containsKey(i)) {
ReportMeterReadingsHis reportMeterReadingsHis = aggregateCreators.get(i).apply(list);
reportMeterReadingsHis.setMtRatio(1);
reportMeterReadingsHis.setSortOrder(i + 1);
reportMeterReadingsHis.setTodayTimestamp(DateUtils.stringToDate(curDate + " 00:00:00", DateUtils.YYYY_MM_DD_HH_MM_SS));
list.add(reportMeterReadingsHis);
}
}
}
private ReportMeterReadingsHis createAggregateObject(String mtType, String location, BigDecimal total, ReportMeterReadingsHis meterReadingsHis) {
ReportMeterReadingsHis reportMeterReadingsHis = new ReportMeterReadingsHis();
reportMeterReadingsHis.setMtType(mtType);
reportMeterReadingsHis.setLocation(location);
reportMeterReadingsHis.setYesterdayReading(new BigDecimal("0"));
reportMeterReadingsHis.setTodayReading(total);
if (meterReadingsHis != null) {
reportMeterReadingsHis.setUnitPrice(meterReadingsHis.getUnitPrice());
} else {
reportMeterReadingsHis.setUnitPrice(new BigDecimal("1"));
}
return reportMeterReadingsHis;
}
private BigDecimal calculateTotalByRange(List<ReportMeterReadingsHis> list, int start, int end) {
if (list == null || list.isEmpty()) {
return BigDecimal.ZERO;
}
return list.stream()
.filter(meterReadingsHis -> meterReadingsHis != null
&& meterReadingsHis.getSortOrder() > start
&& meterReadingsHis.getSortOrder() < end
&& meterReadingsHis.getTotal() != null)
.map(ReportMeterReadingsHis::getTotal)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
private void performFinalInsert(List<ReportMeterReadingsHis> list, String curDate) {
reportMeterReadingsHisMapper.deleteByDate(curDate + " 00:00:00");
if (list != null) {
for (ReportMeterReadingsHis reportMeterReadingsHis : list) {
reportMeterReadingsHis.setTotal(null);
reportMeterReadingsHis.setCost(null);
}
}
reportMeterReadingsHisMapper.insert(list);
list = reportMeterReadingsHisMapper.selectListByDate(curDate + " 00:00:00");
// 添加水表、电表、燃气表、水、电、气费用总合计
ReportMeterReadingsHis totalReportMeterReadingsHis = new ReportMeterReadingsHis();
totalReportMeterReadingsHis.setMtType("总合计");
totalReportMeterReadingsHis.setLocation("水、电、气费用总合计(水/电/气价预估单价,单价需以实际缴费为准):");
totalReportMeterReadingsHis.setYesterdayReading(new BigDecimal("0"));
Set<Integer> sortOrderSet = Set.of(9, 14, 19, 22, 24, 26);
BigDecimal grandTotal = calculateTotalBySpecificValues(list, sortOrderSet);
totalReportMeterReadingsHis.setTodayReading(grandTotal);
totalReportMeterReadingsHis.setMtRatio(1);
totalReportMeterReadingsHis.setSortOrder(27);
totalReportMeterReadingsHis.setUnitPrice(new BigDecimal("1"));
totalReportMeterReadingsHis.setTodayTimestamp(DateUtils.stringToDate(curDate + " 00:00:00", DateUtils.YYYY_MM_DD_HH_MM_SS));
if (list != null) {
list.add(totalReportMeterReadingsHis);
}
reportMeterReadingsHisMapper.deleteByDate(curDate + " 00:00:00");
if (list != null) {
for (ReportMeterReadingsHis reportMeterReadingsHis : list) {
reportMeterReadingsHis.setTotal(null);
reportMeterReadingsHis.setCost(null);
}
}
reportMeterReadingsHisMapper.insert(list);
}
private BigDecimal calculateTotalBySpecificValues(List<ReportMeterReadingsHis> list, Set<Integer> sortOrderSet) {
if (list == null || list.isEmpty()) {
return BigDecimal.ZERO;
}
return list.stream()
.filter(meterReadingsHis -> meterReadingsHis != null
&& sortOrderSet.contains(meterReadingsHis.getSortOrder())
&& meterReadingsHis.getCost() != null)
.map(ReportMeterReadingsHis::getCost)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
@Override
public List<ReportMeterReadingsHis> selectList(ReportMeterReadingsHis todayTimestamp) {
List<ReportMeterReadingsHis> list = null;
if (todayTimestamp == null) {
return null;
}
if (todayTimestamp.getTodayTimestamp() == null) {
list = reportMeterReadingsHisMapper.selectListByDate(DateUtils.parseDateToStr("yyyy-MM-dd 00:00:00", DateUtils.getNowDate()));
} else {
list = reportMeterReadingsHisMapper.selectListByDate(DateUtils.parseDateToStr("yyyy-MM-dd 00:00:00", todayTimestamp.getTodayTimestamp()));
}
// 开始格式化抄表记录
return list;
}
}

121
mh-system/src/main/java/com/mh/system/service/report/impl/ReportHotWaterServiceImpl.java

@ -0,0 +1,121 @@
package com.mh.system.service.report.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mh.common.core.domain.entity.ReportHotWaterParamHis;
import com.mh.common.core.domain.entity.ReportSysRunParamHis;
import com.mh.common.utils.StringUtils;
import com.mh.system.mapper.report.ReportHotWaterParamHisMapper;
import com.mh.system.mapper.report.ReportSysRunParamHisMapper;
import com.mh.system.service.report.IReportHotWaterService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* @author LJF
* @version 1.0
* @project NewZhujiang_Server
* @description 报表服务类
* @date 2024-05-29 11:20:30
*/
@Slf4j
@Service
public class ReportHotWaterServiceImpl implements IReportHotWaterService {
@Resource
ReportHotWaterParamHisMapper reportHotWaterParamHisMapper;
private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Override
public int updateRunParams(ReportHotWaterParamHis reportHotWaterParamHis) {
return reportHotWaterParamHisMapper.updateById(reportHotWaterParamHis);
}
@Override
public void execProRunParamHis() {
try {
log.info("执行计算系统参数存储过程");
// 获取当前日期和时间
LocalDateTime now = LocalDateTime.now();
// 格式化日期和时间
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedOneHourAgo = now.format(formatter);
String timeParam = formattedOneHourAgo.substring(0, 13);
// 创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(2);
// 提交任务
Future<?> future1 = executorService.submit(() -> {
reportHotWaterParamHisMapper.execProHotWaterRunParam(
"73138702b71e16d200b458185bb07e59_-1楼",
"e3dc9e3d0aa7c07d3b6db9ce8c119f3d",
"d6c381f7baa02bbca25fcdbbe367390d",
timeParam
);
log.info("执行计算系统参数存储过程完成: -1楼");
});
Future<?> future2 = executorService.submit(() -> {
reportHotWaterParamHisMapper.execProHotWaterRunParam(
"73138702b71e16d200b458185bb07e59_3楼",
"24c7538214b5f6e707e27095b37aee46",
"5c21b9acf8cd8e049278f39c8d61b16d",
timeParam
);
log.info("执行计算系统参数存储过程完成: 3楼");
});
// 等待任务完成
try {
future1.get();
future2.get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException("存储过程执行失败", e);
} finally {
executorService.shutdown();
}
log.info("执行计算系统参数执行完成");
} catch (Exception e) {
log.error("执行计算系统参数存储过程执行失败", e);
throw new RuntimeException(e);
}
}
@Override
public List<ReportHotWaterParamHis> selectList(ReportHotWaterParamHis reportSysRunParamHis) {
String floorId = reportSysRunParamHis.getFloorId();
if (StringUtils.isEmpty(floorId)) {
// 默认3楼,实际上是buildingId
floorId = "73138702b71e16d200b458185bb07e59_3楼";
}
if (reportSysRunParamHis.getParams() == null) {
reportSysRunParamHis.setParams(new java.util.HashMap<>());
}
String startTime = (String) reportSysRunParamHis.getParams().get("startTime");
String endTime = (String) reportSysRunParamHis.getParams().get("endTime");
if (StringUtils.isBlank(startTime)) {
LocalDateTime now = LocalDateTime.now();
startTime = now.format(dateTimeFormatter).substring(0, 10);
endTime = now.format(dateTimeFormatter).substring(0, 10);
}
startTime = startTime + " 00";
endTime = endTime + " 23";
return reportHotWaterParamHisMapper.selectList(
new QueryWrapper<ReportHotWaterParamHis>()
.between("cur_time", startTime, endTime)
.eq("floor_id", floorId)
.orderByDesc("cur_time"));
}
}

133
sql/2025新增.sql

@ -268,3 +268,136 @@ INSERT INTO public.policy_manage (id, policy_type, policy_name, point_name, inpu
INSERT INTO public.policy_manage (id, policy_type, policy_name, point_name, input_type, unit, cpm_id, order_num, system_type, fun_policy_type, min, max, digits, house_id) VALUES('offset_set_value_006', '9', '定时设置6', '当前偏移值设置', '', NULL, '283034kk26a9b3a79a86332526b24856', 8, '0', '4', NULL, NULL, 0, NULL); INSERT INTO public.policy_manage (id, policy_type, policy_name, point_name, input_type, unit, cpm_id, order_num, system_type, fun_policy_type, min, max, digits, house_id) VALUES('offset_set_value_006', '9', '定时设置6', '当前偏移值设置', '', NULL, '283034kk26a9b3a79a86332526b24856', 8, '0', '4', NULL, NULL, 0, NULL);
INSERT INTO public.policy_manage (id, policy_type, policy_name, point_name, input_type, unit, cpm_id, order_num, system_type, fun_policy_type, min, max, digits, house_id) VALUES('offset_set_value_007', '9', '定时设置7', '当前偏移值设置', '', NULL, '283034kk26a9b3a79a86332526b24856', 8, '0', '4', NULL, NULL, 0, NULL); INSERT INTO public.policy_manage (id, policy_type, policy_name, point_name, input_type, unit, cpm_id, order_num, system_type, fun_policy_type, min, max, digits, house_id) VALUES('offset_set_value_007', '9', '定时设置7', '当前偏移值设置', '', NULL, '283034kk26a9b3a79a86332526b24856', 8, '0', '4', NULL, NULL, 0, NULL);
-- 2025-10-21 添加单价
ALTER TABLE public.collection_params_manage ADD unit_price numeric(10, 3) DEFAULT 0 NULL;
COMMENT ON COLUMN public.collection_params_manage.unit_price IS '单价';
-- public.report_meter_readings_his definition
-- Drop table
-- DROP TABLE public.report_meter_readings_his;
CREATE TABLE public.report_meter_readings_his (
id varchar(36) NOT NULL -- 唯一标识符(自增主键),
mt_type varchar(100) NOT NULL -- 设备类型(如电表、水表),
"location" varchar(255) NOT NULL -- 安装位置(如3楼东侧走廊),
mt_num varchar(50) NULL -- 设备唯一编号(如MTR-001),
yesterday_reading numeric(24, 5) NULL -- 昨日累计读数(非负数),
today_reading numeric(24, 5) NULL -- 今日累计读数(非负数),
mt_ratio int4 DEFAULT 1 NULL -- 倍率(默认1.0,保留两位小数,如1.5表示1.5倍计费),
total numeric(24, 2) GENERATED ALWAYS AS (((today_reading - yesterday_reading) * mt_ratio::numeric)) STORED NULL -- 总用量(自动生成:(今日读数-昨日读数)*倍率),
unit_price numeric(24, 3) NOT NULL -- 单价(单位:元/单位,如0.85元/度),
"cost" numeric(24, 4) GENERATED ALWAYS AS (((today_reading - yesterday_reading) * mt_ratio::numeric * unit_price)) STORED NULL -- 费用(自动生成:总用量×单价),
yesterday_timestamp timestamptz NULL -- 昨日抄表时间(格式:YYYY-MM-DD HH:MI:SS),
today_timestamp timestamptz NULL -- 今日抄表时间(格式:YYYY-MM-DD HH:MI:SS),
sort_order int4 DEFAULT 0 NULL -- 排序序号(数值越小越靠前),
create_time timestamp DEFAULT CURRENT_TIMESTAMP NULL,
CONSTRAINT meter_readings_his_pkey PRIMARY KEY (id),
CONSTRAINT meter_readings_his_today_reading_check CHECK ((today_reading >= (0)::numeric)),
CONSTRAINT meter_readings_his_yesterday_reading_check CHECK ((yesterday_reading >= (0)::numeric))
);
CREATE INDEX idx_today_timestamp ON public.report_meter_readings_his USING btree (today_timestamp);
COMMENT ON INDEX public.idx_today_timestamp IS '按今日抄表时间创建的B-tree索引';
COMMENT ON TABLE public.report_meter_readings_his IS '仪表读数记录表(含自动计算用量及费用)';
-- Column comments
COMMENT ON COLUMN public.report_meter_readings_his.id IS '唯一标识符(自增主键)';
COMMENT ON COLUMN public.report_meter_readings_his.mt_type IS '设备类型(如电表、水表)';
COMMENT ON COLUMN public.report_meter_readings_his."location" IS '安装位置(如3楼东侧走廊)';
COMMENT ON COLUMN public.report_meter_readings_his.mt_num IS '设备唯一编号(如MTR-001)';
COMMENT ON COLUMN public.report_meter_readings_his.yesterday_reading IS '昨日累计读数(非负数)';
COMMENT ON COLUMN public.report_meter_readings_his.today_reading IS '今日累计读数(非负数)';
COMMENT ON COLUMN public.report_meter_readings_his.mt_ratio IS '倍率(默认1.0,保留两位小数,如1.5表示1.5倍计费)';
COMMENT ON COLUMN public.report_meter_readings_his.total IS '总用量(自动生成:(今日读数-昨日读数)*倍率)';
COMMENT ON COLUMN public.report_meter_readings_his.unit_price IS '单价(单位:元/单位,如0.85元/度)';
COMMENT ON COLUMN public.report_meter_readings_his."cost" IS '费用(自动生成:总用量×单价)';
COMMENT ON COLUMN public.report_meter_readings_his.yesterday_timestamp IS '昨日抄表时间(格式:YYYY-MM-DD HH:MI:SS)';
COMMENT ON COLUMN public.report_meter_readings_his.today_timestamp IS '今日抄表时间(格式:YYYY-MM-DD HH:MI:SS)';
COMMENT ON COLUMN public.report_meter_readings_his.sort_order IS '排序序号(数值越小越靠前)';
-- 热泵运行状态表
-- public.report_hot_water_param_his definition
-- Drop table
-- DROP TABLE public.report_hot_water_param_his;
CREATE TABLE public.report_hot_water_param_his (
id varchar(36) NOT NULL -- 主键,唯一标识记录,
floor_id varchar(50) NULL -- 所属楼层ID(关联楼层主表),
cur_date date NULL -- 记录日期(格式:YYYY-MM-DD),
cur_time varchar(20) NULL -- 记录时间(格式:YYYY-MM-DD HH),
classes varchar(50) NULL -- 班次标识(早班/中班/夜班),
temp_set_hot_pump_one numeric(24, 2) NULL -- 1号热泵设定温度(单位:℃),
temp_real_hot_pump_one numeric(24, 2) NULL -- 1号热泵实际温度(单位:℃),
status_switch_hot_pump_one int4 NULL -- 1号热泵启停状态(0-关机,1-开机),
status_run_hot_pump_one int4 NULL -- 1号热泵运行状态(0-停止,1-运行),
temp_set_hot_pump_two numeric(24, 2) NULL -- 2号热泵设定温度(单位:℃),
temp_real_hot_pump_two numeric(24, 2) NULL -- 2号热泵实际温度(单位:℃),
status_switch_hot_pump_two int4 NULL -- 2号热泵启停状态(0-关机,1-开机),
status_run_hot_pump_two int4 NULL -- 2号热泵运行状态(0-停止,1-运行),
temp_set_hot_pump_three numeric(24, 2) NULL -- 3号热泵设定温度(单位:℃),
temp_real_hot_pump_three numeric(24, 2) NULL -- 3号热泵实际温度(单位:℃),
status_switch_hot_pump_three int4 NULL -- 3号热泵启停状态(0-关机,1-开机),
status_run_hot_pump_three int4 NULL -- 3号热泵运行状态(0-停止,1-运行),
temp_set_hot_pump_four numeric(24, 2) NULL -- 4号热泵设定温度(单位:℃),
temp_real_hot_pump_four numeric(24, 2) NULL -- 4号热泵实际温度(单位:℃),
status_switch_hot_pump_four int4 NULL -- 4号热泵启停状态(0-关机,1-开机),
status_run_hot_pump_four int4 NULL -- 4号热泵运行状态(0-停止,1-运行),
pres_set_supply_pump_area_one numeric(24, 2) NULL -- 高区/裙楼设定压力(单位:MPa),
pres_real_supply_pump_area_one numeric(24, 2) NULL -- 高区/裙楼实际压力(单位:MPa),
status_run_supply_pump_one numeric(24, 2) NULL -- 高区/裙楼1号泵运行状态(0-停止,1-运行),
status_run_supply_pump_two numeric(24, 2) NULL -- 高区/裙楼2号泵运行状态(0-停止,1-运行),
pres_set_supply_pump_area_two numeric(24, 2) NULL -- 中区/中厨设定压力(单位:MPa),
pres_real_supply_pump_area_two numeric(24, 2) NULL -- 中区/中厨实际压力(单位:MPa),
status_run_supply_pump_three numeric(24, 2) NULL -- 中区/中厨1号泵运行状态(0-停止,1-运行),
status_run_supply_pump_four numeric(24, 2) NULL -- 中区/中厨2号泵运行状态(0-停止,1-运行),
level_water_tank_one numeric(24, 2) NULL -- 高区/裙楼液位(单位:%),
level_water_tank_two numeric(24, 2) NULL -- 中区/中厨液位(单位:%),
recorder varchar(50) NULL -- 巡查记录人(工号/姓名),
remark varchar(200) NULL -- 异常情况备注说明,
create_time timestamp DEFAULT CURRENT_TIMESTAMP NULL -- 记录生成时间(含时区信息),
CONSTRAINT report_hot_water_param_his_pkey PRIMARY KEY (id)
);
CREATE INDEX idx_cur_time ON public.report_hot_water_param_his USING brin (cur_time);
CREATE INDEX idx_floor_date ON public.report_hot_water_param_his USING btree (floor_id, cur_date);
COMMENT ON TABLE public.report_hot_water_param_his IS '热水系统历史参数记录表,存储各热泵、水泵的运行状态及环境参数';
-- Column comments
COMMENT ON COLUMN public.report_hot_water_param_his.id IS '主键,唯一标识记录';
COMMENT ON COLUMN public.report_hot_water_param_his.floor_id IS '所属楼层ID(关联楼层主表)';
COMMENT ON COLUMN public.report_hot_water_param_his.cur_date IS '记录日期(格式:YYYY-MM-DD)';
COMMENT ON COLUMN public.report_hot_water_param_his.cur_time IS '记录时间(格式:YYYY-MM-DD HH)';
COMMENT ON COLUMN public.report_hot_water_param_his.classes IS '班次标识(早班/中班/夜班)';
COMMENT ON COLUMN public.report_hot_water_param_his.temp_set_hot_pump_one IS '1号热泵设定温度(单位:℃)';
COMMENT ON COLUMN public.report_hot_water_param_his.temp_real_hot_pump_one IS '1号热泵实际温度(单位:℃)';
COMMENT ON COLUMN public.report_hot_water_param_his.status_switch_hot_pump_one IS '1号热泵启停状态(0-关机,1-开机)';
COMMENT ON COLUMN public.report_hot_water_param_his.status_run_hot_pump_one IS '1号热泵运行状态(0-停止,1-运行)';
COMMENT ON COLUMN public.report_hot_water_param_his.temp_set_hot_pump_two IS '2号热泵设定温度(单位:℃)';
COMMENT ON COLUMN public.report_hot_water_param_his.temp_real_hot_pump_two IS '2号热泵实际温度(单位:℃)';
COMMENT ON COLUMN public.report_hot_water_param_his.status_switch_hot_pump_two IS '2号热泵启停状态(0-关机,1-开机)';
COMMENT ON COLUMN public.report_hot_water_param_his.status_run_hot_pump_two IS '2号热泵运行状态(0-停止,1-运行)';
COMMENT ON COLUMN public.report_hot_water_param_his.temp_set_hot_pump_three IS '3号热泵设定温度(单位:℃)';
COMMENT ON COLUMN public.report_hot_water_param_his.temp_real_hot_pump_three IS '3号热泵实际温度(单位:℃)';
COMMENT ON COLUMN public.report_hot_water_param_his.status_switch_hot_pump_three IS '3号热泵启停状态(0-关机,1-开机)';
COMMENT ON COLUMN public.report_hot_water_param_his.status_run_hot_pump_three IS '3号热泵运行状态(0-停止,1-运行)';
COMMENT ON COLUMN public.report_hot_water_param_his.temp_set_hot_pump_four IS '4号热泵设定温度(单位:℃)';
COMMENT ON COLUMN public.report_hot_water_param_his.temp_real_hot_pump_four IS '4号热泵实际温度(单位:℃)';
COMMENT ON COLUMN public.report_hot_water_param_his.status_switch_hot_pump_four IS '4号热泵启停状态(0-关机,1-开机)';
COMMENT ON COLUMN public.report_hot_water_param_his.status_run_hot_pump_four IS '4号热泵运行状态(0-停止,1-运行)';
COMMENT ON COLUMN public.report_hot_water_param_his.pres_set_supply_pump_area_one IS '高区/裙楼设定压力(单位:MPa)';
COMMENT ON COLUMN public.report_hot_water_param_his.pres_real_supply_pump_area_one IS '高区/裙楼实际压力(单位:MPa)';
COMMENT ON COLUMN public.report_hot_water_param_his.status_run_supply_pump_one IS '高区/裙楼1号泵运行状态(0-停止,1-运行)';
COMMENT ON COLUMN public.report_hot_water_param_his.status_run_supply_pump_two IS '高区/裙楼2号泵运行状态(0-停止,1-运行)';
COMMENT ON COLUMN public.report_hot_water_param_his.pres_set_supply_pump_area_two IS '中区/中厨设定压力(单位:MPa)';
COMMENT ON COLUMN public.report_hot_water_param_his.pres_real_supply_pump_area_two IS '中区/中厨实际压力(单位:MPa)';
COMMENT ON COLUMN public.report_hot_water_param_his.status_run_supply_pump_three IS '中区/中厨1号泵运行状态(0-停止,1-运行)';
COMMENT ON COLUMN public.report_hot_water_param_his.status_run_supply_pump_four IS '中区/中厨2号泵运行状态(0-停止,1-运行)';
COMMENT ON COLUMN public.report_hot_water_param_his.level_water_tank_one IS '高区/裙楼液位(单位:%)';
COMMENT ON COLUMN public.report_hot_water_param_his.level_water_tank_two IS '中区/中厨液位(单位:%)';
COMMENT ON COLUMN public.report_hot_water_param_his.recorder IS '巡查记录人(工号/姓名)';
COMMENT ON COLUMN public.report_hot_water_param_his.remark IS '异常情况备注说明';
COMMENT ON COLUMN public.report_hot_water_param_his.create_time IS '记录生成时间(含时区信息)';

281
sql/创建热水运行报表存储过程20251023.sql

@ -0,0 +1,281 @@
CREATE OR REPLACE PROCEDURE "public"."pro_hot_water_run_param"("floor_id_in" varchar, "floor_id_1_in" varchar, "floor_id_2_in" varchar, "cur_time_in" varchar)
AS $BODY$
DECLARE
-- 变量声明(保持原有结构,默认值优化)
temp_set_hot_pump_one NUMERIC(24,2) := 0;
temp_real_hot_pump_one NUMERIC(24,2) := 0;
status_switch_hot_pump_one INT := 0;
status_run_hot_pump_one INT := 0;
temp_set_hot_pump_two NUMERIC(24,2) := 0;
temp_real_hot_pump_two NUMERIC(24,2) := 0;
status_switch_hot_pump_two INT := 0;
status_run_hot_pump_two INT := 0;
temp_set_hot_pump_three NUMERIC(24,2) := 0;
temp_real_hot_pump_three NUMERIC(24,2) := 0;
status_switch_hot_pump_three INT := 0;
status_run_hot_pump_three INT := 0;
temp_set_hot_pump_four NUMERIC(24,2) := 0;
temp_real_hot_pump_four NUMERIC(24,2) := 0;
status_switch_hot_pump_four INT := 0;
status_run_hot_pump_four INT := 0;
pres_set_supply_pump_area_one NUMERIC(24,2) := 0;
pres_real_supply_pump_area_one NUMERIC(24,2) := 0;
status_run_supply_pump_one INT := 0;
status_run_supply_pump_two INT := 0;
pres_set_supply_pump_area_two NUMERIC(24,2) := 0;
pres_real_supply_pump_area_two NUMERIC(24,2) := 0;
status_run_supply_pump_three INT := 0;
status_run_supply_pump_four INT := 0;
level_water_tank_one NUMERIC(24,2) := 0;
level_water_tank_two NUMERIC(24,2) := 0;
is_exits INT := 0;
register_address VARCHAR(50);
other_name VARCHAR(50);
value NUMERIC(24,2);
mt_num varchar(20);
-- 游标1:中区/中厨
base_param_1 CURSOR FOR
select
cpm.mt_num::VARCHAR,
COALESCE(MAX(cpm.cur_value), 0)::NUMERIC(24,2)
from
collection_params_manage cpm
left join device_ledger dl on
cpm.device_ledger_id = dl.id
left join cpm_space_relation csr on
cpm.id = csr.cpm_id
left join house_info hi on
csr.house_id = hi.id
where
csr.floor_id = floor_id_2_in
and cpm.system_type = '1'
and cpm.is_use = 0
and hi.house_name is not null
AND TO_CHAR(cpm.cur_time, 'YYYY-MM-DD HH24') = cur_time_in
GROUP BY
cpm.cur_time::DATE,
cpm.mt_num;
-- 游标2:高区/裙楼
base_param_2 CURSOR FOR
select
cpm.other_name::VARCHAR,
cpm.mt_num::VARCHAR,
COALESCE(MAX(cpm.cur_value), 0)::NUMERIC(24,2)
from
collection_params_manage cpm
left join device_ledger dl on
cpm.device_ledger_id = dl.id
left join cpm_space_relation csr on
cpm.id = csr.cpm_id
left join house_info hi on
csr.house_id = hi.id
where
csr.floor_id = floor_id_1_in
and cpm.system_type = '1'
and cpm.is_use = 0
and hi.house_name is not null
AND TO_CHAR(cpm.cur_time, 'YYYY-MM-DD HH24') = cur_time_in
GROUP BY
cpm.other_name::VARCHAR,
cpm.cur_time::DATE,
cpm.mt_num;
BEGIN
-- ------------------------------
-- 4. 遍历游标获取寄存器参数(严格关闭游标)高区/裙楼
-- ------------------------------
OPEN base_param_1;
BEGIN -- 游标操作的异常处理块
LOOP
FETCH NEXT FROM base_param_1 INTO register_address, value;
EXIT WHEN NOT FOUND;
-- 根据寄存器地址映射参数值
case
WHEN register_address in ('1VD04000','2VD04000') THEN pres_set_supply_pump_area_two := value;
WHEN register_address in ('1VD01500','2VD01500') THEN pres_real_supply_pump_area_two := value;
WHEN register_address in ('1I00007','2I00007') THEN status_run_supply_pump_three := value;
WHEN register_address in ('1I00012','2I00012') THEN status_run_supply_pump_four := value;
WHEN register_address in ('1VD09200','2VD09200') THEN level_water_tank_two := value;
ELSE
-- 记录未匹配的寄存器地址(新增)
RAISE NOTICE '未匹配的寄存器地址(设备:%): %', floor_id_1_in, register_address;
END CASE;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
-- 游标异常时记录错误
RAISE NOTICE '游标遍历失败(设备:%): %', floor_id_1_in, SQLERRM;
END;
CLOSE base_param_1; -- 确保游标最终关闭
RAISE NOTICE '关闭游标';
-- ------------------------------
-- 4. 遍历游标获取寄存器参数(严格关闭游标)中区/中厨
-- ------------------------------
OPEN base_param_2;
BEGIN
LOOP
FETCH NEXT FROM base_param_2 INTO other_name, register_address, value;
EXIT WHEN NOT FOUND;
CASE
-- 合并判断条件(推荐写法)
WHEN other_name in ('3号热泵温度设置','1号热泵温度设置') and register_address IN ('1', '3') THEN
temp_set_hot_pump_one := value;
WHEN other_name in ('3号热泵实际温度','1号热泵实际温度') and register_address IN ('1', '3') THEN
temp_real_hot_pump_one := value;
WHEN other_name in ('3号热泵启停控制','1号热泵启停控制') and register_address IN ('1', '3') THEN
status_switch_hot_pump_one := CASE WHEN value > 1 THEN 1 ELSE 0 END;
WHEN other_name in ('3号热泵电流1','1号热泵电流1') and register_address IN ('1', '3') THEN
temp_real_hot_pump_one := CASE WHEN value > 1 THEN 1 ELSE 0 END;
WHEN other_name in ('4号热泵温度设置','2号热泵温度设置') and register_address IN ('2', '4') THEN
temp_set_hot_pump_two := value;
WHEN other_name in ('4号热泵实际温度','2号热泵实际温度') and register_address IN ('2', '4') THEN
temp_real_hot_pump_two := value;
WHEN other_name in ('4号热泵启停控制','2号热泵启停控制') and register_address IN ('2', '4') THEN
status_switch_hot_pump_two := CASE WHEN value > 1 THEN 1 ELSE 0 END;
WHEN other_name in ('4号热泵电流1','2号热泵电流1') and register_address IN ('2', '4') THEN
temp_real_hot_pump_two := CASE WHEN value > 1 THEN 1 ELSE 0 END;
WHEN other_name in ('5号热泵温度设置') and register_address IN ('5') THEN
temp_set_hot_pump_three := value;
WHEN other_name in ('5号热泵实际温度') and register_address IN ('5') THEN
temp_real_hot_pump_three := value;
WHEN other_name in ('5号热泵启停控制') and register_address IN ('5') THEN
status_switch_hot_pump_three := CASE WHEN value > 1 THEN 1 ELSE 0 END;
WHEN other_name in ('5号热泵电流1') and register_address IN ('5') THEN
temp_real_hot_pump_three := CASE WHEN value > 1 THEN 1 ELSE 0 END;
WHEN other_name in ('6号热泵温度设置') and register_address IN ('6') THEN
temp_set_hot_pump_four := value;
WHEN other_name in ('6号热泵实际温度') and register_address IN ('6') THEN
temp_real_hot_pump_four := value;
WHEN other_name in ('6号热泵启停控制') and register_address IN ('6') THEN
status_switch_hot_pump_four := CASE WHEN value > 1 THEN 1 ELSE 0 END;
WHEN other_name in ('6号热泵电流1') and register_address IN ('6') THEN
temp_real_hot_pump_four := CASE WHEN value > 1 THEN 1 ELSE 0 END;
WHEN register_address IN ('1VD07000', '2VD07000') THEN
pres_set_supply_pump_area_one := value;
WHEN register_address IN ('1VD01800', '2VD01800') THEN
pres_real_supply_pump_area_one := value;
WHEN register_address IN ('1I00001', '2I00001') THEN
status_run_supply_pump_one := value;
WHEN register_address IN ('1I00004', '2I00004') THEN
status_run_supply_pump_two := value;
WHEN register_address IN ('2VD06100', '1VD06100') THEN
level_water_tank_one := value;
ELSE
RAISE NOTICE '设备类型或寄存器地址不匹配(设备:%): %', floor_id_2_in, register_address;
END CASE;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE '游标遍历失败(设备:%): %', floor_id_2_in, SQLERRM;
END;
CLOSE base_param_2; -- 确保游标最终关闭
RAISE NOTICE '关闭游标';
-- ------------------------------
-- 5. 插入历史数据(处理唯一约束冲突)
-- ------------------------------
SELECT COUNT(1) INTO is_exits
FROM report_hot_water_param_his
WHERE cur_time = cur_time_in
AND floor_id = floor_id_in;
IF is_exits = 0 THEN
INSERT INTO public.report_hot_water_param_his (
id,
floor_id,
cur_date,
cur_time,
temp_set_hot_pump_one,
temp_real_hot_pump_one,
status_switch_hot_pump_one,
status_run_hot_pump_one,
temp_set_hot_pump_two,
temp_real_hot_pump_two,
status_switch_hot_pump_two,
status_run_hot_pump_two,
temp_set_hot_pump_three,
temp_real_hot_pump_three,
status_switch_hot_pump_three,
status_run_hot_pump_three,
temp_set_hot_pump_four,
temp_real_hot_pump_four,
status_switch_hot_pump_four,
status_run_hot_pump_four,
pres_set_supply_pump_area_one,
pres_real_supply_pump_area_one,
status_run_supply_pump_one,
status_run_supply_pump_two,
pres_set_supply_pump_area_two,
pres_real_supply_pump_area_two,
status_run_supply_pump_three,
status_run_supply_pump_four,
level_water_tank_one,
level_water_tank_two
) VALUES (
uuid_generate_v1mc(),
floor_id_in,
LEFT(cur_time_in, 10)::DATE,
cur_time_in,
temp_set_hot_pump_one,
temp_real_hot_pump_one,
status_switch_hot_pump_one,
status_run_hot_pump_one,
temp_set_hot_pump_two,
temp_real_hot_pump_two,
status_switch_hot_pump_two,
status_run_hot_pump_two,
temp_set_hot_pump_three,
temp_real_hot_pump_three,
status_switch_hot_pump_three,
status_run_hot_pump_three,
temp_set_hot_pump_four,
temp_real_hot_pump_four,
status_switch_hot_pump_four,
status_run_hot_pump_four,
pres_set_supply_pump_area_one,
pres_real_supply_pump_area_one,
status_run_supply_pump_one,
status_run_supply_pump_two,
pres_set_supply_pump_area_two,
pres_real_supply_pump_area_two,
status_run_supply_pump_three,
status_run_supply_pump_four,
level_water_tank_one,
level_water_tank_two
);
END IF;
EXCEPTION
WHEN OTHERS THEN
-- 主事务异常时,记录错误
RAISE NOTICE '存储过程执行失败(设备:%,时间:%): %',
floor_id_in, cur_time_in, SQLERRM;
END;
$BODY$
LANGUAGE plpgsql
Loading…
Cancel
Save