diff --git a/doc/节能改造每日能耗统计表.xlsx b/doc/节能改造每日能耗统计表.xlsx new file mode 100644 index 0000000..13f5f4f Binary files /dev/null and b/doc/节能改造每日能耗统计表.xlsx differ diff --git a/mh-admin/src/main/java/com/mh/web/controller/report/ReportHotWaterController.java b/mh-admin/src/main/java/com/mh/web/controller/report/ReportHotWaterController.java new file mode 100644 index 0000000..bb5cec9 --- /dev/null +++ b/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 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 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 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 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("下载报表异常"); + } + } + +} diff --git a/mh-admin/src/main/java/com/mh/web/controller/report/ReportMeterReadingsController.java b/mh-admin/src/main/java/com/mh/web/controller/report/ReportMeterReadingsController.java new file mode 100644 index 0000000..ea800ac --- /dev/null +++ b/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 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 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 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 map = new HashMap<>(); + + List weatherTemp = (List) 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; + } + +} diff --git a/mh-admin/src/main/resources/application.yml b/mh-admin/src/main/resources/application.yml index c3ae7c3..44f7920 100644 --- a/mh-admin/src/main/resources/application.yml +++ b/mh-admin/src/main/resources/application.yml @@ -1,6 +1,6 @@ spring: profiles: - active: dev + active: prod # 用户配置 user: diff --git a/mh-admin/src/main/resources/节能岛改造每日能耗统计表.xlsx b/mh-admin/src/main/resources/节能岛改造每日能耗统计表.xlsx new file mode 100644 index 0000000..0faaa02 Binary files /dev/null and b/mh-admin/src/main/resources/节能岛改造每日能耗统计表.xlsx differ diff --git a/mh-admin/src/test/java/com/mh/MHApplicationTest.java b/mh-admin/src/test/java/com/mh/MHApplicationTest.java index 219ccc6..050a319 100644 --- a/mh-admin/src/test/java/com/mh/MHApplicationTest.java +++ b/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.device.IDeviceQrManageService; 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 org.checkerframework.checker.units.qual.A; import org.junit.jupiter.api.Test; @@ -48,6 +50,22 @@ public class MHApplicationTest { @Autowired 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 public void createAlarmTask() { alarmRecordsService.insertOrUpdateAlarmRecord("e1a3034edw6a9b3a79a86332886b24896"); diff --git a/mh-common/src/main/java/com/mh/common/core/domain/dto/BFloorReportHotWaterDTO.java b/mh-common/src/main/java/com/mh/common/core/domain/dto/BFloorReportHotWaterDTO.java new file mode 100644 index 0000000..c14a2de --- /dev/null +++ b/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; + +} diff --git a/mh-common/src/main/java/com/mh/common/core/domain/dto/ThreeFloorReportHotWaterDTO.java b/mh-common/src/main/java/com/mh/common/core/domain/dto/ThreeFloorReportHotWaterDTO.java new file mode 100644 index 0000000..75f44c6 --- /dev/null +++ b/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; + +} diff --git a/mh-common/src/main/java/com/mh/common/core/domain/entity/ReportHotWaterParamHis.java b/mh-common/src/main/java/com/mh/common/core/domain/entity/ReportHotWaterParamHis.java new file mode 100644 index 0000000..497ba2c --- /dev/null +++ b/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 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(); + } +} diff --git a/mh-common/src/main/java/com/mh/common/core/domain/entity/ReportMeterReadingsHis.java b/mh-common/src/main/java/com/mh/common/core/domain/entity/ReportMeterReadingsHis.java new file mode 100644 index 0000000..3b5180f --- /dev/null +++ b/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(); + } +} diff --git a/mh-quartz/src/main/java/com/mh/quartz/task/ReportTask.java b/mh-quartz/src/main/java/com/mh/quartz/task/ReportTask.java new file mode 100644 index 0000000..96e9f29 --- /dev/null +++ b/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(); + } + +} diff --git a/mh-system/src/main/java/com/mh/system/mapper/report/ReportHotWaterParamHisMapper.java b/mh-system/src/main/java/com/mh/system/mapper/report/ReportHotWaterParamHisMapper.java new file mode 100644 index 0000000..2e82c3b --- /dev/null +++ b/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 { + + @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 findPage(@Param("floorId") String floorId, + @Param("beginDate") String beginDate, + @Param("endDate") String endDate); +} diff --git a/mh-system/src/main/java/com/mh/system/mapper/report/ReportMeterReadingsHisMapper.java b/mh-system/src/main/java/com/mh/system/mapper/report/ReportMeterReadingsHisMapper.java new file mode 100644 index 0000000..9a741da --- /dev/null +++ b/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 { + + @Select("select * from report_meter_readings_his where today_timestamp = #{curDate}::timestamp order by sort_order ") + List 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 selectRecordListByDate(String tableName, String curDate); + + @Delete("delete from report_meter_readings_his where today_timestamp = #{curDate}::timestamp") + void deleteByDate(@ Param("curDate") String curDate); +} diff --git a/mh-system/src/main/java/com/mh/system/service/report/IMeterReadingsHisService.java b/mh-system/src/main/java/com/mh/system/service/report/IMeterReadingsHisService.java new file mode 100644 index 0000000..9b02bf9 --- /dev/null +++ b/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 selectList(ReportMeterReadingsHis todayTimestamp); + +} diff --git a/mh-system/src/main/java/com/mh/system/service/report/IReportHotWaterService.java b/mh-system/src/main/java/com/mh/system/service/report/IReportHotWaterService.java new file mode 100644 index 0000000..312d0b8 --- /dev/null +++ b/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 selectList(ReportHotWaterParamHis reportHotWaterParamHis); + + int updateRunParams(ReportHotWaterParamHis reportHotWaterParamHis); +} diff --git a/mh-system/src/main/java/com/mh/system/service/report/impl/MeterReadingsHisServiceImpl.java b/mh-system/src/main/java/com/mh/system/service/report/impl/MeterReadingsHisServiceImpl.java new file mode 100644 index 0000000..cc173e6 --- /dev/null +++ b/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 locationList = List.of( + "磁悬浮3号空调主机", + "变频5号冷冻泵", + "4号冷冻泵", + "变频5号冷却泵", + "4号冷却泵", + "变频1号冷却塔", + "变频2号冷却塔", + "变频3号冷却塔", + "空调系统用电总合计:", + "三楼热泵控制柜", + "三楼变频水泵控制柜", + "洗衣房热泵控制柜", + "群楼中厨水泵控制柜", + "热水热泵系统用电总合计:", + "空调冷冻水", + "空调冷却水", + "三楼中、高区热水", + "群楼、中厨房热水", + "热水热泵系统用水总合计:", + "蒸汽发生器+采暖", + "蒸汽发生器+采暖", + "蒸汽发生器+采暖用气总合计:", + "蒸汽发生器+采暖", + "蒸汽发生器+采暖用电总合计:", + "蒸汽发生器+采暖", + "蒸汽发生器用水总合计:", + "水、电、气费用总合计(水/电/气价预估单价,单价需以实际缴费为准):", + "中央空调冷冻流量", + "中央空调冷却流量", + "中央空调采暖流量", + "蒸汽流量" + ); + + private final List mtTypeList = List.of( + "电表", + "电表", + "电表", + "电表", + "电表", + "电表", + "电表", + "电表", + "电表", + "电表", + "电表", + "电表", + "电表", + "电表", + "水表", + "水表", + "水表", + "水表", + "水表", + "燃气表(常用)", + "燃气表(备用)", + "燃气表", + "电表", + "电表", + "水表", + "水表", + "总合计", + "流量计量表", + "流量计量表", + "流量计量表", + "流量计量表" + ); + + @Override + public void execProMeterReadingsHis(String curDate) { + // 根据时间查询对应的每日的采集抄表记录 + String tableName = "data_day" + StringUtils.substring(curDate, 0, 4); + List list = reportMeterReadingsHisMapper.selectRecordListByDate(tableName, curDate); + if (null == list) { + return; + } + reportMeterReadingsHisMapper.deleteByDate(curDate + " 00:00:00"); + // 循环处理数据 + List 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 processLocationMatching(List originalList, String curDate) { + List filteredList = new ArrayList<>(); + for (int i = 0; i < locationList.size(); i++) { + int finalI = i; + Optional 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 handleDatabaseOperations(List list, String curDate) { + List 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 list, String curDate) { + Map, 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 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 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 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 list, Set 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 selectList(ReportMeterReadingsHis todayTimestamp) { + List 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; + } +} diff --git a/mh-system/src/main/java/com/mh/system/service/report/impl/ReportHotWaterServiceImpl.java b/mh-system/src/main/java/com/mh/system/service/report/impl/ReportHotWaterServiceImpl.java new file mode 100644 index 0000000..48a6630 --- /dev/null +++ b/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 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() + .between("cur_time", startTime, endTime) + .eq("floor_id", floorId) + .orderByDesc("cur_time")); + } +} diff --git a/sql/2025新增.sql b/sql/2025新增.sql index b94b1d3..5640192 100644 --- a/sql/2025新增.sql +++ b/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_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 '记录生成时间(含时区信息)'; diff --git a/sql/创建热水运行报表存储过程20251023.sql b/sql/创建热水运行报表存储过程20251023.sql new file mode 100644 index 0000000..da108cd --- /dev/null +++ b/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 \ No newline at end of file