From b27f049c9fd2560907dd170f382969358d7281af Mon Sep 17 00:00:00 2001 From: cdf <857448963@qq.com> Date: Sat, 17 Jan 2026 13:43:24 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9B=91=E6=B5=8B=E7=82=B9=E6=8A=A5=E5=91=8A?= =?UTF-8?q?=E6=8A=BD=E5=8F=96=E5=85=AC=E5=85=B1=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../device/biz}/mapper/OverlimitMapper.java | 2 +- .../biz}/mapper/mapping/OverlimitMapper.xml | 2 +- .../njcn/device/biz/pojo/po/Overlimit.java | 75 - .../service/impl/TerminalBaseServiceImpl.java | 2 +- .../line/service/impl/LineServiceImpl.java | 2 +- .../service/impl/OverLimitServiceImpl.java | 2 +- .../controller/RStatLimitRateDController.java | 4 +- .../RStatLimitRateDetailDController.java | 4 +- .../report/CustomReportController.java | 2 +- .../report/ExportModelController.java | 1833 +---------------- .../mapper/RStatLimitRateDMapper.java | 2 +- .../mapper/RStatLimitRateDetailDMapper.java | 2 +- .../mapper/mapping/RStatDataIDMapper.xml | 2 +- .../mapping/RStatDataInharmVDMapper.xml | 2 +- .../mapper/mapping/RStatDataVDMapper.xml | 2 +- .../mapper/mapping/RStatLimitRateDMapper.xml | 0 .../mapping/RStatLimitRateDetailDMapper.xml | 0 .../service/IRStatLimitRateDService.java | 2 +- .../IRStatLimitRateDetailDService.java | 2 +- .../service/impl/AnalyzeServiceImpl.java | 2 +- .../service/impl/GridServiceImpl.java | 5 +- .../impl/HistoryResultServiceImpl.java | 9 +- .../impl/PollutionSubstationServiceImpl.java | 2 +- .../service/impl/RStatDataVDServiceImpl.java | 2 +- .../impl/RStatLimitRateDServiceImpl.java | 6 +- .../RStatLimitRateDetailDServiceImpl.java | 8 +- .../service/impl/ReportServiceImpl.java | 51 +- .../impl/SteadyExceedRateServiceImpl.java | 6 +- .../impl/SteadyQualifyServiceImpl.java | 6 +- .../RMpPartHarmonicDetailDServiceImpl.java | 5 +- .../impl/RStatLimitServiceImpl.java | 2 +- .../service/report/CustomReportService.java | 2 +- .../report/impl/CustomReportServiceImpl.java | 355 ++-- .../impl/REvaluationDataServiceImpl.java | 6 +- .../main/resources/file/reportModelWL.docx | Bin 0 -> 79682 bytes pqs-harmonic/harmonic-common/pom.xml | 7 +- .../common}/mapper/ExcelRptTempMapper.java | 7 +- .../mapper/MonitorCommReportMapper.java | 137 ++ .../mapper/RStatDataHarmRateVDMapper.java | 2 +- .../common}/mapper/RStatDataIDMapper.java | 4 +- .../mapper/RStatDataInharmVDMapper.java | 2 +- .../common}/mapper/RStatDataVDMapper.java | 3 +- .../mapper/mapping/ExcelRptTempMapper.xml | 8 +- .../mapping/MonitorCommReportMapper.xml | 467 +++++ .../common/pojo/dto/DeviceUnitCommDTO.java | 117 ++ .../common/pojo/dto/LineDetailDataCommVO.java | 134 ++ .../common/pojo/dto/OverLimitInfoCommDTO.java | 870 ++++++++ .../common}/pojo/vo/ReportTemplateVO.java | 2 +- .../service/CustomReportTableService.java | 25 + .../service/MonitorCommReportService.java | 96 + .../service/MonitorHarmonicReportService.java | 29 + .../impl/CustomReportTableServiceImpl.java | 788 +++++++ .../impl/MonitorCommReportServiceImpl.java | 692 +++++++ .../MonitorHarmonicReportServiceImpl.java | 1830 ++++++++++++++++ .../common/service/impl/RegroupDataComm.java} | 4 +- 55 files changed, 5491 insertions(+), 2142 deletions(-) rename pqs-device/{pq-device/pq-device-com/src/main/java/com/njcn/device/overlimit => common-device-biz/src/main/java/com/njcn/device/biz}/mapper/OverlimitMapper.java (92%) rename pqs-device/{pq-device/pq-device-com/src/main/java/com/njcn/device/overlimit => common-device-biz/src/main/java/com/njcn/device/biz}/mapper/mapping/OverlimitMapper.xml (91%) rename pqs-harmonic/{harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate => harmonic-boot/src/main/java/com/njcn/harmonic}/controller/RStatLimitRateDController.java (98%) rename pqs-harmonic/{harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate => harmonic-boot/src/main/java/com/njcn/harmonic}/controller/RStatLimitRateDetailDController.java (97%) rename pqs-harmonic/{harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate => harmonic-boot/src/main/java/com/njcn/harmonic}/mapper/RStatLimitRateDMapper.java (98%) rename pqs-harmonic/{harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate => harmonic-boot/src/main/java/com/njcn/harmonic}/mapper/RStatLimitRateDetailDMapper.java (81%) rename pqs-harmonic/{harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate => harmonic-boot/src/main/java/com/njcn/harmonic}/mapper/mapping/RStatLimitRateDMapper.xml (100%) rename pqs-harmonic/{harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate => harmonic-boot/src/main/java/com/njcn/harmonic}/mapper/mapping/RStatLimitRateDetailDMapper.xml (100%) rename pqs-harmonic/{harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate => harmonic-boot/src/main/java/com/njcn/harmonic}/service/IRStatLimitRateDService.java (97%) rename pqs-harmonic/{harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate => harmonic-boot/src/main/java/com/njcn/harmonic}/service/IRStatLimitRateDetailDService.java (95%) rename pqs-harmonic/{harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate => harmonic-boot/src/main/java/com/njcn/harmonic}/service/impl/RStatLimitRateDServiceImpl.java (99%) rename pqs-harmonic/{harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate => harmonic-boot/src/main/java/com/njcn/harmonic}/service/impl/RStatLimitRateDetailDServiceImpl.java (98%) create mode 100644 pqs-harmonic/harmonic-boot/src/main/resources/file/reportModelWL.docx rename pqs-harmonic/{harmonic-boot/src/main/java/com/njcn/harmonic => harmonic-common/src/main/java/com/njcn/harmonic/common}/mapper/ExcelRptTempMapper.java (85%) create mode 100644 pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/MonitorCommReportMapper.java rename pqs-harmonic/{harmonic-boot/src/main/java/com/njcn/harmonic => harmonic-common/src/main/java/com/njcn/harmonic/common}/mapper/RStatDataHarmRateVDMapper.java (86%) rename pqs-harmonic/{harmonic-boot/src/main/java/com/njcn/harmonic => harmonic-common/src/main/java/com/njcn/harmonic/common}/mapper/RStatDataIDMapper.java (83%) rename pqs-harmonic/{harmonic-boot/src/main/java/com/njcn/harmonic => harmonic-common/src/main/java/com/njcn/harmonic/common}/mapper/RStatDataInharmVDMapper.java (92%) rename pqs-harmonic/{harmonic-boot/src/main/java/com/njcn/harmonic => harmonic-common/src/main/java/com/njcn/harmonic/common}/mapper/RStatDataVDMapper.java (93%) rename pqs-harmonic/{harmonic-boot/src/main/java/com/njcn/harmonic => harmonic-common/src/main/java/com/njcn/harmonic/common}/mapper/mapping/ExcelRptTempMapper.xml (79%) create mode 100644 pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/mapping/MonitorCommReportMapper.xml create mode 100644 pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/pojo/dto/DeviceUnitCommDTO.java create mode 100644 pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/pojo/dto/LineDetailDataCommVO.java create mode 100644 pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/pojo/dto/OverLimitInfoCommDTO.java rename pqs-harmonic/{harmonic-api/src/main/java/com/njcn/harmonic => harmonic-common/src/main/java/com/njcn/harmonic/common}/pojo/vo/ReportTemplateVO.java (92%) create mode 100644 pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/CustomReportTableService.java create mode 100644 pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/MonitorCommReportService.java create mode 100644 pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/MonitorHarmonicReportService.java create mode 100644 pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/CustomReportTableServiceImpl.java create mode 100644 pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/MonitorCommReportServiceImpl.java create mode 100644 pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/MonitorHarmonicReportServiceImpl.java rename pqs-harmonic/{harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/RegroupData.java => harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/RegroupDataComm.java} (93%) diff --git a/pqs-device/pq-device/pq-device-com/src/main/java/com/njcn/device/overlimit/mapper/OverlimitMapper.java b/pqs-device/common-device-biz/src/main/java/com/njcn/device/biz/mapper/OverlimitMapper.java similarity index 92% rename from pqs-device/pq-device/pq-device-com/src/main/java/com/njcn/device/overlimit/mapper/OverlimitMapper.java rename to pqs-device/common-device-biz/src/main/java/com/njcn/device/biz/mapper/OverlimitMapper.java index 6b34315f1..c55566419 100644 --- a/pqs-device/pq-device/pq-device-com/src/main/java/com/njcn/device/overlimit/mapper/OverlimitMapper.java +++ b/pqs-device/common-device-biz/src/main/java/com/njcn/device/biz/mapper/OverlimitMapper.java @@ -1,4 +1,4 @@ -package com.njcn.device.overlimit.mapper; +package com.njcn.device.biz.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; diff --git a/pqs-device/pq-device/pq-device-com/src/main/java/com/njcn/device/overlimit/mapper/mapping/OverlimitMapper.xml b/pqs-device/common-device-biz/src/main/java/com/njcn/device/biz/mapper/mapping/OverlimitMapper.xml similarity index 91% rename from pqs-device/pq-device/pq-device-com/src/main/java/com/njcn/device/overlimit/mapper/mapping/OverlimitMapper.xml rename to pqs-device/common-device-biz/src/main/java/com/njcn/device/biz/mapper/mapping/OverlimitMapper.xml index fb1720efe..76ca26274 100644 --- a/pqs-device/pq-device/pq-device-com/src/main/java/com/njcn/device/overlimit/mapper/mapping/OverlimitMapper.xml +++ b/pqs-device/common-device-biz/src/main/java/com/njcn/device/biz/mapper/mapping/OverlimitMapper.xml @@ -1,6 +1,6 @@ - + select diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/mapping/RStatDataInharmVDMapper.xml b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/mapping/RStatDataInharmVDMapper.xml index dc5d51b83..5bfbd993b 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/mapping/RStatDataInharmVDMapper.xml +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/mapping/RStatDataInharmVDMapper.xml @@ -1,6 +1,6 @@ - + select diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate/mapper/mapping/RStatLimitRateDMapper.xml b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/mapping/RStatLimitRateDMapper.xml similarity index 100% rename from pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate/mapper/mapping/RStatLimitRateDMapper.xml rename to pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/mapping/RStatLimitRateDMapper.xml diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate/mapper/mapping/RStatLimitRateDetailDMapper.xml b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/mapping/RStatLimitRateDetailDMapper.xml similarity index 100% rename from pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate/mapper/mapping/RStatLimitRateDetailDMapper.xml rename to pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/mapping/RStatLimitRateDetailDMapper.xml diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate/service/IRStatLimitRateDService.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/IRStatLimitRateDService.java similarity index 97% rename from pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate/service/IRStatLimitRateDService.java rename to pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/IRStatLimitRateDService.java index b2f4e4a55..c094775d9 100644 --- a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate/service/IRStatLimitRateDService.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/IRStatLimitRateDService.java @@ -1,4 +1,4 @@ -package com.njcn.harmonic.rstatlimitrate.service; +package com.njcn.harmonic.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate/service/IRStatLimitRateDetailDService.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/IRStatLimitRateDetailDService.java similarity index 95% rename from pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate/service/IRStatLimitRateDetailDService.java rename to pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/IRStatLimitRateDetailDService.java index 1645dda1d..6880af46d 100644 --- a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate/service/IRStatLimitRateDetailDService.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/IRStatLimitRateDetailDService.java @@ -1,4 +1,4 @@ -package com.njcn.harmonic.rstatlimitrate.service; +package com.njcn.harmonic.service; import cn.hutool.json.JSONArray; import com.baomidou.mybatisplus.extension.service.IService; diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/AnalyzeServiceImpl.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/AnalyzeServiceImpl.java index e9e7df18b..d59a175a0 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/AnalyzeServiceImpl.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/AnalyzeServiceImpl.java @@ -33,7 +33,7 @@ import com.njcn.harmonic.pojo.vo.MonitorOverLimitVO; import com.njcn.harmonic.pojo.vo.OverAreaLimitVO; import com.njcn.harmonic.pojo.vo.OverAreaVO; import com.njcn.harmonic.pojo.vo.WarningSubstationVO; -import com.njcn.harmonic.rstatlimitrate.mapper.RStatLimitRateDMapper; +import com.njcn.harmonic.mapper.RStatLimitRateDMapper; import com.njcn.harmonic.service.IAnalyzeService; import com.njcn.poi.excel.ExcelUtil; import com.njcn.supervision.api.UserLedgerFeignClient; diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/GridServiceImpl.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/GridServiceImpl.java index 77989fcd5..20d6c0ce1 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/GridServiceImpl.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/GridServiceImpl.java @@ -23,7 +23,10 @@ import com.njcn.harmonic.pojo.vo.hebeinorth.AssessDetailVo; import com.njcn.harmonic.pojo.vo.hebeinorth.AssessVo; import com.njcn.harmonic.pojo.vo.hebeinorth.EvaluationLevelVo; import com.njcn.harmonic.pojo.vo.hebeinorth.EvaluationVo; -import com.njcn.harmonic.rstatlimitrate.mapper.RStatLimitRateDMapper; +import com.njcn.harmonic.common.mapper.RStatDataIDMapper; +import com.njcn.harmonic.common.mapper.RStatDataInharmVDMapper; +import com.njcn.harmonic.common.mapper.RStatDataVDMapper; +import com.njcn.harmonic.mapper.RStatLimitRateDMapper; import com.njcn.harmonic.service.hebeinorth.IGridService; import com.njcn.harmonic.util.ComAssesUtil; import com.njcn.harmonic.util.TimeUtil; diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/HistoryResultServiceImpl.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/HistoryResultServiceImpl.java index 7dfeedbdf..06629b48f 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/HistoryResultServiceImpl.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/HistoryResultServiceImpl.java @@ -12,7 +12,6 @@ import com.njcn.common.pojo.constant.BizParamConstant; import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.pojo.param.StatisticsBizBaseParam; import com.njcn.common.utils.PubUtils; -import com.njcn.dataProcess.pojo.po.RStatDataHarmRateVD; import com.njcn.device.biz.commApi.CommTerminalGeneralClient; import com.njcn.device.biz.pojo.dto.LineDevGetDTO; import com.njcn.device.biz.pojo.po.Overlimit; @@ -20,7 +19,6 @@ import com.njcn.device.biz.pojo.po.PqsDeviceUnit; import com.njcn.device.biz.utils.COverlimitUtil; import com.njcn.event.api.EventDetailFeignClient; import com.njcn.event.pojo.po.EventDetail; -import com.njcn.event.pojo.po.RmpEventDetailPO; import com.njcn.harmonic.enums.HarmonicResponseEnum; import com.njcn.harmonic.mapper.*; import com.njcn.harmonic.pojo.QueryResultLimitVO; @@ -33,8 +31,10 @@ import com.njcn.harmonic.pojo.vo.AssessEvaluation; import com.njcn.harmonic.pojo.vo.EventDetailVO; import com.njcn.harmonic.pojo.vo.HistoryDataResultVO; import com.njcn.harmonic.pojo.vo.StatHarmonicOrgVO; +import com.njcn.harmonic.common.mapper.RStatDataHarmRateVDMapper; +import com.njcn.harmonic.common.mapper.RStatDataIDMapper; +import com.njcn.harmonic.common.mapper.RStatDataVDMapper; import com.njcn.harmonic.service.HistoryResultService; -import com.njcn.harmonic.service.IRStatDataVDService; import com.njcn.influx.imapper.CommonMapper; import com.njcn.influx.imapper.DataHarmRateVMapper; import com.njcn.influx.imapper.DataIMapper; @@ -50,14 +50,11 @@ import com.njcn.system.pojo.po.DictData; import com.njcn.user.api.DeptFeignClient; import com.njcn.user.pojo.dto.DeptDTO; import com.njcn.web.utils.WebUtil; -import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/PollutionSubstationServiceImpl.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/PollutionSubstationServiceImpl.java index 1639042c9..62d4c3f18 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/PollutionSubstationServiceImpl.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/PollutionSubstationServiceImpl.java @@ -58,7 +58,7 @@ import com.njcn.harmonic.pojo.po.day.RStatLimitRateDPO; import com.njcn.harmonic.pojo.vo.PollutionSubstationVO; import com.njcn.harmonic.pojo.vo.PollutionVO; import com.njcn.harmonic.pojo.vo.SubstationVo; -import com.njcn.harmonic.rstatlimitrate.mapper.RStatLimitRateDMapper; +import com.njcn.harmonic.mapper.RStatLimitRateDMapper; import com.njcn.harmonic.service.PollutionSubstationService; import com.njcn.poi.excel.ExcelUtil; import com.njcn.supervision.api.UserLedgerFeignClient; diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/RStatDataVDServiceImpl.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/RStatDataVDServiceImpl.java index 8195474b7..f7046d327 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/RStatDataVDServiceImpl.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/RStatDataVDServiceImpl.java @@ -1,7 +1,7 @@ package com.njcn.harmonic.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.njcn.harmonic.mapper.RStatDataVDMapper; +import com.njcn.harmonic.common.mapper.RStatDataVDMapper; import com.njcn.harmonic.pojo.po.RStatDataVD; import com.njcn.harmonic.service.IRStatDataVDService; import org.springframework.stereotype.Service; diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate/service/impl/RStatLimitRateDServiceImpl.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/RStatLimitRateDServiceImpl.java similarity index 99% rename from pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate/service/impl/RStatLimitRateDServiceImpl.java rename to pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/RStatLimitRateDServiceImpl.java index 700c12344..6ee1c32ac 100644 --- a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate/service/impl/RStatLimitRateDServiceImpl.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/RStatLimitRateDServiceImpl.java @@ -1,4 +1,4 @@ -package com.njcn.harmonic.rstatlimitrate.service.impl; +package com.njcn.harmonic.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; @@ -19,8 +19,8 @@ import com.njcn.harmonic.pojo.param.TotalLimitStatisticsDetailsQueryParam; import com.njcn.harmonic.pojo.param.TotalLimitStatisticsParam; import com.njcn.harmonic.pojo.po.day.RStatLimitRateDPO; import com.njcn.harmonic.pojo.vo.*; -import com.njcn.harmonic.rstatlimitrate.mapper.RStatLimitRateDMapper; -import com.njcn.harmonic.rstatlimitrate.service.IRStatLimitRateDService; +import com.njcn.harmonic.mapper.RStatLimitRateDMapper; +import com.njcn.harmonic.service.IRStatLimitRateDService; import com.njcn.system.api.DicDataFeignClient; import com.njcn.system.pojo.po.DictData; import lombok.RequiredArgsConstructor; diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate/service/impl/RStatLimitRateDetailDServiceImpl.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/RStatLimitRateDetailDServiceImpl.java similarity index 98% rename from pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate/service/impl/RStatLimitRateDetailDServiceImpl.java rename to pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/RStatLimitRateDetailDServiceImpl.java index 2687a4c60..e79851ed7 100644 --- a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/rstatlimitrate/service/impl/RStatLimitRateDetailDServiceImpl.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/RStatLimitRateDetailDServiceImpl.java @@ -1,4 +1,4 @@ -package com.njcn.harmonic.rstatlimitrate.service.impl; +package com.njcn.harmonic.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Pair; @@ -24,9 +24,9 @@ import com.njcn.harmonic.pojo.vo.LimitCalendarVO; import com.njcn.harmonic.pojo.vo.LimitExtentVO; import com.njcn.harmonic.pojo.vo.LimitProbabilityVO; import com.njcn.harmonic.pojo.vo.LimitTimeProbabilityVO; -import com.njcn.harmonic.rstatlimitrate.mapper.RStatLimitRateDetailDMapper; -import com.njcn.harmonic.rstatlimitrate.service.IRStatLimitRateDService; -import com.njcn.harmonic.rstatlimitrate.service.IRStatLimitRateDetailDService; +import com.njcn.harmonic.mapper.RStatLimitRateDetailDMapper; +import com.njcn.harmonic.service.IRStatLimitRateDService; +import com.njcn.harmonic.service.IRStatLimitRateDetailDService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/ReportServiceImpl.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/ReportServiceImpl.java index beb700c00..4e6926464 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/ReportServiceImpl.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/ReportServiceImpl.java @@ -4,9 +4,9 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.njcn.harmonic.mapper.RStatDataHarmRateVDMapper; -import com.njcn.harmonic.mapper.RStatDataIDMapper; -import com.njcn.harmonic.mapper.RStatDataInharmVDMapper; +import com.njcn.harmonic.common.mapper.RStatDataHarmRateVDMapper; +import com.njcn.harmonic.common.mapper.RStatDataIDMapper; +import com.njcn.harmonic.common.mapper.RStatDataInharmVDMapper; import com.njcn.harmonic.mapper.ReportMapper; import com.njcn.harmonic.pojo.po.RStatDataVD; import com.njcn.harmonic.pojo.po.day.RStatDataHarmrateVDPO; @@ -15,6 +15,7 @@ import com.njcn.harmonic.pojo.param.ReportQueryParam; import com.njcn.harmonic.pojo.po.day.RStatDataInharmVDPO; import com.njcn.harmonic.pojo.po.report.OverLimitInfo; import com.njcn.harmonic.pojo.vo.ReportValue; +import com.njcn.harmonic.common.service.impl.RegroupDataComm; import com.njcn.harmonic.service.IRStatDataVDService; import com.njcn.harmonic.service.ReportService; import lombok.RequiredArgsConstructor; @@ -74,9 +75,9 @@ public class ReportServiceImpl implements ReportService { //获取线电压有效值 List listVV = reportMapper.getVVirtualData(param); - RegroupData.regroupData(listV, true); - RegroupData.regroupData(listI, true); - RegroupData.regroupData(listVV, true); + RegroupDataComm.regroupData(listV, true); + RegroupDataComm.regroupData(listI, true); + RegroupDataComm.regroupData(listVV, true); list.addAll(listV); list.addAll(listI); list.addAll(listVV); @@ -96,10 +97,10 @@ public class ReportServiceImpl implements ReportService { //获取功率因数 List listF = reportMapper.getPF(param); - RegroupData.regroupData(listP, true, false); - RegroupData.regroupData(listQ, true, false); - RegroupData.regroupData(listS, true, false); - RegroupData.regroupData(listF, true, false); + RegroupDataComm.regroupData(listP, true, false); + RegroupDataComm.regroupData(listQ, true, false); + RegroupDataComm.regroupData(listS, true, false); + RegroupDataComm.regroupData(listF, true, false); list.addAll(listP); list.addAll(listQ); list.addAll(listS); @@ -116,8 +117,8 @@ public class ReportServiceImpl implements ReportService { //长时闪变 List listLFlicker = reportMapper.getLFlickerData(param); - RegroupData.regroupData(listFlicker, true); - RegroupData.regroupData(listLFlicker, true); + RegroupDataComm.regroupData(listFlicker, true); + RegroupDataComm.regroupData(listLFlicker, true); list.addAll(listFlicker); list.addAll(listLFlicker); @@ -132,8 +133,8 @@ public class ReportServiceImpl implements ReportService { List listU = reportMapper.getUVdeviationData(param); List listL = reportMapper.getLVdeviationData(param); - RegroupData.regroupData(listU, true); - RegroupData.regroupData(listL, true); + RegroupDataComm.regroupData(listU, true); + RegroupDataComm.regroupData(listL, true); list.addAll(listU); list.addAll(listL); return list; @@ -148,8 +149,8 @@ public class ReportServiceImpl implements ReportService { List listI = reportMapper.getDistortionDataI(param); //添加之前判断数据库是否有数据,如果没有数据模拟数据添加到集合中 - RegroupData.regroupData(listU, true); - RegroupData.regroupData(listI, true); + RegroupDataComm.regroupData(listU, true); + RegroupDataComm.regroupData(listI, true); list.addAll(listU); list.addAll(listI); @@ -164,8 +165,8 @@ public class ReportServiceImpl implements ReportService { List listFreDEV = reportMapper.getDEVFrequencyData(param); - RegroupData.regroupData(listFre, true); - RegroupData.regroupData(listFreDEV, true); + RegroupDataComm.regroupData(listFre, true); + RegroupDataComm.regroupData(listFreDEV, true); list.addAll(listFre); list.addAll(listFreDEV); return list; @@ -201,7 +202,7 @@ public class ReportServiceImpl implements ReportService { List listI = dataI(param, Arrays.asList("A", "B", "C"), 1, 51, false, 0); if (CollUtil.isEmpty(listI)) { for (int i = 0; i < 50; i++) { - RegroupData.regroupData(list, true, true); + RegroupDataComm.regroupData(list, true, true); } } else { list.addAll(listI); @@ -217,7 +218,7 @@ public class ReportServiceImpl implements ReportService { List listV = dataV(param, Arrays.asList("A", "B", "C"), 1, 2, false, 5); if (CollUtil.isEmpty(listV)) { - RegroupData.regroupData(list, true, true); + RegroupDataComm.regroupData(list, true, true); } else { list.addAll(listV); } @@ -227,7 +228,7 @@ public class ReportServiceImpl implements ReportService { if (CollUtil.isEmpty(listRate)) { for (int i = 0; i < 49; i++) { - RegroupData.regroupData(list, true, true); + RegroupDataComm.regroupData(list, true, true); } } else { list.addAll(listRate); @@ -235,7 +236,7 @@ public class ReportServiceImpl implements ReportService { //获取电压畸变率 List listU = reportMapper.getDistortionDataV(param); - RegroupData.regroupData(listU, true); + RegroupDataComm.regroupData(listU, true); list.addAll(listU); return list; } @@ -290,7 +291,7 @@ public class ReportServiceImpl implements ReportService { }); if (CollUtil.isEmpty(a)) { for (int i = 1; i < 17; i++) { - RegroupData.regroupData(a, true, true); + RegroupDataComm.regroupData(a, true, true); } } return a; @@ -301,7 +302,7 @@ public class ReportServiceImpl implements ReportService { List list = new ArrayList<>(); //负序电流 List iNegData = reportMapper.getINegData(param); - RegroupData.regroupData(iNegData, true); + RegroupDataComm.regroupData(iNegData, true); list.addAll(iNegData); return list; } @@ -310,7 +311,7 @@ public class ReportServiceImpl implements ReportService { private void regroupData(List list) { for (int i = 0; i < 4; i++) { List list1 = new ArrayList<>(); - RegroupData.regroupData(list1, false); + RegroupDataComm.regroupData(list1, false); list.addAll(list1); } } diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/SteadyExceedRateServiceImpl.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/SteadyExceedRateServiceImpl.java index 0f5e28779..2ac66c824 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/SteadyExceedRateServiceImpl.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/SteadyExceedRateServiceImpl.java @@ -20,8 +20,7 @@ import com.njcn.harmonic.pojo.po.day.RStatLimitRateDPO; import com.njcn.harmonic.pojo.vo.MonitorOverLimitVO; import com.njcn.harmonic.pojo.vo.SteadyExceedRateCensusVO; import com.njcn.harmonic.pojo.vo.SteadyExceedRateVO; -import com.njcn.harmonic.rstatlimitrate.mapper.RStatLimitRateDMapper; -import com.njcn.harmonic.rstatlimitrate.service.IRStatLimitRateDService; +import com.njcn.harmonic.mapper.RStatLimitRateDMapper; import com.njcn.harmonic.service.SteadyExceedRateService; import com.njcn.harmonic.utils.PubUtils; import com.njcn.influx.pojo.constant.InfluxDBTableConstant; @@ -53,7 +52,6 @@ public class SteadyExceedRateServiceImpl implements SteadyExceedRateService { private final GeneralDeviceInfoClient generalDeviceInfoClient; private final SteadyExceedRateMapper steadyExceedRateMapper; - private final IRStatLimitRateDService rateDService; private final RStatLimitRateDMapper rateDMapper; private final UserLedgerFeignClient userLedgerFeignClient; @@ -531,7 +529,7 @@ public class SteadyExceedRateServiceImpl implements SteadyExceedRateService { */ private List getQualifiesRate(List lineIndexes, String startTime, String endTime) { List limitRatePOS = new ArrayList<>(); - List limitRates = rateDService.list(new LambdaQueryWrapper() + List limitRates = rateDMapper.selectList(new LambdaQueryWrapper() .in(RStatLimitRateDPO::getLineId, lineIndexes) .eq(RStatLimitRateDPO::getPhasicType, InfluxDBTableConstant.PHASE_TYPE_T) .ge(StrUtil.isNotBlank(startTime), RStatLimitRateDPO::getTime, DateUtil.beginOfDay(DateUtil.parse(startTime))) diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/SteadyQualifyServiceImpl.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/SteadyQualifyServiceImpl.java index e9403bdbc..fd44252e7 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/SteadyQualifyServiceImpl.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/SteadyQualifyServiceImpl.java @@ -13,12 +13,12 @@ import com.njcn.device.pq.enums.LineBaseEnum; import com.njcn.device.pq.pojo.dto.GeneralDeviceDTO; import com.njcn.device.pq.pojo.param.DeviceInfoParam; import com.njcn.device.pq.pojo.vo.LineDetailVO; +import com.njcn.harmonic.mapper.RStatLimitRateDMapper; import com.njcn.harmonic.mapper.SteadyQualifyMapper; import com.njcn.harmonic.pojo.po.day.RStatLimitRateDPO; import com.njcn.harmonic.pojo.vo.SteadyQualifyCensusVO; import com.njcn.harmonic.pojo.vo.SteadyQualifyDetailVO; import com.njcn.harmonic.pojo.vo.SteadyQualifyVO; -import com.njcn.harmonic.rstatlimitrate.service.IRStatLimitRateDService; import com.njcn.harmonic.service.SteadyQualifyService; import com.njcn.harmonic.utils.PubUtils; import com.njcn.supervision.api.UserLedgerFeignClient; @@ -45,7 +45,7 @@ public class SteadyQualifyServiceImpl implements SteadyQualifyService { private final SteadyQualifyMapper steadyQualifyMapper; - private final IRStatLimitRateDService rateDService; + private final RStatLimitRateDMapper rStatLimitRateDMapper; private final UserLedgerFeignClient userLedgerFeignClient; @@ -543,7 +543,7 @@ public class SteadyQualifyServiceImpl implements SteadyQualifyService { * @param endTime */ private List getQualifiesRate(List lineIndexes, String startTime, String endTime) { - return rateDService.list(new LambdaQueryWrapper() + return rStatLimitRateDMapper.selectList(new LambdaQueryWrapper() .in(RStatLimitRateDPO::getLineId, lineIndexes) .eq(RStatLimitRateDPO::getPhasicType, "T") .ge(StrUtil.isNotBlank(startTime), RStatLimitRateDPO::getTime, DateUtil.beginOfDay(DateUtil.parse(startTime))) diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/majornetwork/impl/RMpPartHarmonicDetailDServiceImpl.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/majornetwork/impl/RMpPartHarmonicDetailDServiceImpl.java index 4b442d8d0..ab1b51884 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/majornetwork/impl/RMpPartHarmonicDetailDServiceImpl.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/majornetwork/impl/RMpPartHarmonicDetailDServiceImpl.java @@ -1,9 +1,6 @@ package com.njcn.harmonic.service.majornetwork.impl; import cn.hutool.core.collection.CollectionUtil; -import cn.hutool.core.date.DatePattern; -import cn.hutool.core.date.DateTime; -import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.njcn.common.pojo.param.StatisticsBizBaseParam; @@ -16,7 +13,7 @@ import com.njcn.harmonic.pojo.param.RMpPartHarmonicDetailQueryParam; import com.njcn.harmonic.pojo.po.RMpPartHarmonicDetailD; import com.njcn.harmonic.pojo.po.day.RStatLimitRateDPO; import com.njcn.harmonic.pojo.vo.RMpPartHarmonicDetailIconVO; -import com.njcn.harmonic.rstatlimitrate.service.IRStatLimitRateDService; +import com.njcn.harmonic.service.IRStatLimitRateDService; import com.njcn.harmonic.service.majornetwork.RMpPartHarmonicDetailDService; import com.njcn.system.api.DicDataFeignClient; import com.njcn.system.enums.DicDataEnum; diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/majornetwork/impl/RStatLimitServiceImpl.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/majornetwork/impl/RStatLimitServiceImpl.java index 7b1e2c2bd..ecea946a6 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/majornetwork/impl/RStatLimitServiceImpl.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/majornetwork/impl/RStatLimitServiceImpl.java @@ -33,7 +33,7 @@ import com.njcn.harmonic.pojo.po.day.RStatLimitTargetDPO; import com.njcn.harmonic.pojo.vo.MonitorLimitRateVO; import com.njcn.harmonic.pojo.vo.PwLimitDataVO; import com.njcn.harmonic.pojo.vo.RStatLimitTargetVO; -import com.njcn.harmonic.rstatlimitrate.mapper.RStatLimitRateDMapper; +import com.njcn.harmonic.mapper.RStatLimitRateDMapper; import com.njcn.harmonic.service.IRStatLimitTargetDService; import com.njcn.harmonic.service.majornetwork.RStatLimitService; import com.njcn.system.pojo.enums.StatisticsEnum; diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/report/CustomReportService.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/report/CustomReportService.java index d6985d8a6..e86859187 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/report/CustomReportService.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/report/CustomReportService.java @@ -3,7 +3,7 @@ package com.njcn.harmonic.service.report; import com.njcn.harmonic.pojo.param.ReportSearchParam; import com.njcn.harmonic.pojo.param.ReportTemplateParam; import com.njcn.harmonic.pojo.po.ExcelRptTemp; -import com.njcn.harmonic.pojo.vo.ReportTemplateVO; +import com.njcn.harmonic.common.pojo.vo.ReportTemplateVO; import com.njcn.harmonic.pojo.vo.ReportTreeVO; import com.njcn.harmonic.pojo.vo.SysDeptTempVO; diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/report/impl/CustomReportServiceImpl.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/report/impl/CustomReportServiceImpl.java index 4c277aeca..6223ee98f 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/report/impl/CustomReportServiceImpl.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/report/impl/CustomReportServiceImpl.java @@ -23,7 +23,7 @@ import com.njcn.device.biz.pojo.po.PqsDeviceUnit; import com.njcn.harmonic.enums.HarmonicResponseEnum; import com.njcn.harmonic.mapper.DeptTempMapper; import com.njcn.harmonic.mapper.EleEpdMapper; -import com.njcn.harmonic.mapper.ExcelRptTempMapper; +import com.njcn.harmonic.common.mapper.ExcelRptTempMapper; import com.njcn.harmonic.pojo.dto.ReportTemplateDTO; import com.njcn.harmonic.pojo.param.ReportSearchParam; import com.njcn.harmonic.pojo.param.ReportTemplateParam; @@ -39,7 +39,7 @@ import com.njcn.system.pojo.po.DictData; import com.njcn.system.pojo.po.EleEpdPqd; import com.njcn.harmonic.pojo.po.ExcelRptTemp; import com.njcn.harmonic.pojo.po.SysDeptTemp; -import com.njcn.harmonic.pojo.vo.ReportTemplateVO; +import com.njcn.harmonic.common.pojo.vo.ReportTemplateVO; import com.njcn.harmonic.pojo.vo.ReportTreeVO; import com.njcn.harmonic.pojo.vo.SysDeptTempVO; import com.njcn.harmonic.service.report.CustomReportService; @@ -101,7 +101,7 @@ public class CustomReportServiceImpl implements CustomReportService { private final WlRecordFeignClient wlRecordFeignClient; private final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1); - + private final String CELL_DATA = "celldata"; private final String V = "v"; private final String STR_ONE = "#"; @@ -1167,6 +1167,115 @@ public class CustomReportServiceImpl implements CustomReportService { } + + + /** + * 对多测点数据进行计算求出一组数据 + * @param method + * @param allList + * @return + */ + private Map dealResultMap(String method, List> allList) { + Map resultMap = new HashMap<>(); + // 遍历列表中的每个Map + if (method.equals(InfluxDbSqlConstant.MIN)) { + for (Map map : allList) { + // 遍历当前Map的键值对 + for (Map.Entry entry : map.entrySet()) { + String key = entry.getKey(); + if (Objects.nonNull(entry.getValue()) && !key.equals("time")) { + double value = (double) entry.getValue(); + // 检查结果Map中是否已包含该键 + if (!resultMap.containsKey(key) || (double) resultMap.get(key) > value) { + // 如果不包含,或当前值更大,则更新结果Map + resultMap.put(key, value); + } + } + } + } + } else if (method.equals(InfluxDbSqlConstant.MAX) || method.equals(InfluxDbSqlConstant.PERCENTILE)) { + for (Map map : allList) { + // 遍历当前Map的键值对 + for (Map.Entry entry : map.entrySet()) { + String key = entry.getKey(); + if (Objects.nonNull(entry.getValue()) && !key.equals("time")) { + double value = (double) entry.getValue(); + // 检查结果Map中是否已包含该键 + if (!resultMap.containsKey(key) || (double) resultMap.get(key) < value) { + // 如果不包含,或当前值更大,则更新结果Map + resultMap.put(key, value); + } + } + } + } + } else if (method.equals(InfluxDbSqlConstant.AVG)) { + Map sumMap = new HashMap<>(); + Map countMap = new HashMap<>(); + // 遍历列表中的每个Map + for (Map map : allList) { + // 遍历当前Map的键值对 + for (Map.Entry entry : map.entrySet()) { + String key = entry.getKey(); + if (Objects.nonNull(entry.getValue()) && !key.equals("time")) { + double value = (double) entry.getValue(); + + // 更新累计和 + sumMap.put(key, sumMap.getOrDefault(key, 0.0) + value); + // 更新计数 + countMap.put(key, countMap.getOrDefault(key, 0) + 1); + } + } + } + + // 计算平均值并存储到结果Map中 + for (String key : sumMap.keySet()) { + double sum = sumMap.get(key); + int count = countMap.get(key); + double average = BigDecimal.valueOf(sum / count).setScale(3, RoundingMode.HALF_UP).doubleValue(); + resultMap.put(key, average); + } + } + + return resultMap; + } + + + + /** + * 处理指标超标结论 + */ + private void dealTargetResult + (Map assNoPassMap, Map limitTargetMapX, List endList) { + assNoPassMap.forEach((key, val) -> { + limitTargetMapX.remove(key); + if ("Freq_Dev".toUpperCase().equals(val.getTemplateName())) { + val.setValue("±" + val.getValue()); + } + + String expend = ""; + if(Objects.nonNull(val.getLowValue())){ + expend = val.getLowValue()+","; + } + if (val.getOverLimitFlag() == 1) { + val.setValue("不合格 (" + expend+val.getValue() + ")"); + } else { + val.setValue("合格 (" + expend+val.getValue() + ")"); + } + endList.add(val); + }); + + limitTargetMapX.forEach((key, val) -> { + if (Objects.isNull(val.getOverLimitFlag())) { + val.setValue("/"); + } else { + val.setValue("合格"); + } + endList.add(val); + }); + } + + + private void analyzeReportZhejiang(ReportSearchParam reportSearchParam, ExcelRptTemp excelRptTemp, HttpServletResponse response) { //指标 List reportTemplateDTOList = new ArrayList<>(); @@ -1438,178 +1547,6 @@ public class CustomReportServiceImpl implements CustomReportService { endList.addAll(data); } - - /** - * 对多测点数据进行计算求出一组数据 - * @param method - * @param allList - * @return - */ - private Map dealResultMap(String method, List> allList) { - Map resultMap = new HashMap<>(); - // 遍历列表中的每个Map - if (method.equals(InfluxDbSqlConstant.MIN)) { - for (Map map : allList) { - // 遍历当前Map的键值对 - for (Map.Entry entry : map.entrySet()) { - String key = entry.getKey(); - if (Objects.nonNull(entry.getValue()) && !key.equals("time")) { - double value = (double) entry.getValue(); - // 检查结果Map中是否已包含该键 - if (!resultMap.containsKey(key) || (double) resultMap.get(key) > value) { - // 如果不包含,或当前值更大,则更新结果Map - resultMap.put(key, value); - } - } - } - } - } else if (method.equals(InfluxDbSqlConstant.MAX) || method.equals(InfluxDbSqlConstant.PERCENTILE)) { - for (Map map : allList) { - // 遍历当前Map的键值对 - for (Map.Entry entry : map.entrySet()) { - String key = entry.getKey(); - if (Objects.nonNull(entry.getValue()) && !key.equals("time")) { - double value = (double) entry.getValue(); - // 检查结果Map中是否已包含该键 - if (!resultMap.containsKey(key) || (double) resultMap.get(key) < value) { - // 如果不包含,或当前值更大,则更新结果Map - resultMap.put(key, value); - } - } - } - } - } else if (method.equals(InfluxDbSqlConstant.AVG)) { - Map sumMap = new HashMap<>(); - Map countMap = new HashMap<>(); - // 遍历列表中的每个Map - for (Map map : allList) { - // 遍历当前Map的键值对 - for (Map.Entry entry : map.entrySet()) { - String key = entry.getKey(); - if (Objects.nonNull(entry.getValue()) && !key.equals("time")) { - double value = (double) entry.getValue(); - - // 更新累计和 - sumMap.put(key, sumMap.getOrDefault(key, 0.0) + value); - // 更新计数 - countMap.put(key, countMap.getOrDefault(key, 0) + 1); - } - } - } - - // 计算平均值并存储到结果Map中 - for (String key : sumMap.keySet()) { - double sum = sumMap.get(key); - int count = countMap.get(key); - double average = BigDecimal.valueOf(sum / count).setScale(3, RoundingMode.HALF_UP).doubleValue(); - resultMap.put(key, average); - } - } - - return resultMap; - } - - - private void dealExcelResult(JSONArray - jsonArray, Map> assMap, Map unit,Map finalTerminalMap) { - jsonArray.forEach(item -> { - JSONObject jsonObject = (JSONObject) item; - JSONArray itemArr = (JSONArray) jsonObject.get(CELL_DATA); - itemArr.forEach((it) -> { - if (Objects.nonNull(it) && !"null".equals(it.toString())) { - //获取到1列 - JSONObject data = (JSONObject) it; - JSONObject son = (JSONObject) data.get(V); - if (son.containsKey(V)) { - String v = son.getStr(V); - //数据格式:$HA[_25]#B#max#classId$ 或 $HA[_25]#max#classId$ - if (v.charAt(0) == '$' && v.contains(STR_ONE)) { - String str = ""; - List rDto = assMap.get(v.replace(STR_TWO, "")); - if (Objects.nonNull(rDto)) { - str = rDto.get(0).getValue(); - //没有值,赋"/" - if (StringUtils.isBlank(str)) { - str = "/"; - } - son.set(V, str); - if (Objects.nonNull(rDto.get(0).getOverLimitFlag()) && rDto.get(0).getOverLimitFlag() == 1) { - son.set("fc", "#990000"); - } - } - } else if (v.charAt(0) == '%' && v.contains(STR_ONE)) { - //指标合格情况 - String str = ""; - List rDto = assMap.get(v.replace(STR_FOUR, "")); - if (Objects.nonNull(rDto)) { - str = rDto.get(0).getValue(); - //没有值,赋"/" - if (StringUtils.isBlank(str)) { - str = "/"; - } - son.set(V, str); - if ("不合格".equals(str)) { - son.set("fc", "#990000"); - } - } - } else if (v.charAt(0) == '&') { - //结论 - String tem = v.replace(STR_THREE, ""); - if (Objects.nonNull(finalTerminalMap)) { - if ("statis_time".equals(tem)) { - // son.set(V, reportSearchParam.getStartTime() + InfluxDbSqlConstant.START_TIME + "_" + reportSearchParam.getEndTime() + InfluxDbSqlConstant.END_TIME); - } else { - //台账信息 - son.set(V, finalTerminalMap.getOrDefault(tem, "/")); - } - } - } else if (v.charAt(0) == '@' && v.contains(STR_ONE)) { - //解决数据单位问题 @指标#类型@ - String replace = v.replace("@", ""); - son.set(V, unit.getOrDefault(replace, "/")); - - } - } - } - }); - }); - } - - - /** - * 处理指标超标结论 - */ - private void dealTargetResult - (Map assNoPassMap, Map limitTargetMapX, List endList) { - assNoPassMap.forEach((key, val) -> { - limitTargetMapX.remove(key); - if ("Freq_Dev".toUpperCase().equals(val.getTemplateName())) { - val.setValue("±" + val.getValue()); - } - - String expend = ""; - if(Objects.nonNull(val.getLowValue())){ - expend = val.getLowValue()+","; - } - if (val.getOverLimitFlag() == 1) { - val.setValue("不合格 (" + expend+val.getValue() + ")"); - } else { - val.setValue("合格 (" + expend+val.getValue() + ")"); - } - endList.add(val); - }); - - limitTargetMapX.forEach((key, val) -> { - if (Objects.isNull(val.getOverLimitFlag())) { - val.setValue("/"); - } else { - val.setValue("合格"); - } - endList.add(val); - }); - } - - /** * 解析模板 * @@ -1689,6 +1626,74 @@ public class CustomReportServiceImpl implements CustomReportService { } } + + private void dealExcelResult(JSONArray + jsonArray, Map> assMap, Map unit,Map finalTerminalMap) { + jsonArray.forEach(item -> { + JSONObject jsonObject = (JSONObject) item; + JSONArray itemArr = (JSONArray) jsonObject.get(CELL_DATA); + itemArr.forEach((it) -> { + if (Objects.nonNull(it) && !"null".equals(it.toString())) { + //获取到1列 + JSONObject data = (JSONObject) it; + JSONObject son = (JSONObject) data.get(V); + if (son.containsKey(V)) { + String v = son.getStr(V); + //数据格式:$HA[_25]#B#max#classId$ 或 $HA[_25]#max#classId$ + if (v.charAt(0) == '$' && v.contains(STR_ONE)) { + String str = ""; + List rDto = assMap.get(v.replace(STR_TWO, "")); + if (Objects.nonNull(rDto)) { + str = rDto.get(0).getValue(); + //没有值,赋"/" + if (StringUtils.isBlank(str)) { + str = "/"; + } + son.set(V, str); + if (Objects.nonNull(rDto.get(0).getOverLimitFlag()) && rDto.get(0).getOverLimitFlag() == 1) { + son.set("fc", "#990000"); + } + } + } else if (v.charAt(0) == '%' && v.contains(STR_ONE)) { + //指标合格情况 + String str = ""; + List rDto = assMap.get(v.replace(STR_FOUR, "")); + if (Objects.nonNull(rDto)) { + str = rDto.get(0).getValue(); + //没有值,赋"/" + if (StringUtils.isBlank(str)) { + str = "/"; + } + son.set(V, str); + if ("不合格".equals(str)) { + son.set("fc", "#990000"); + } + } + } else if (v.charAt(0) == '&') { + //结论 + String tem = v.replace(STR_THREE, ""); + if (Objects.nonNull(finalTerminalMap)) { + if ("statis_time".equals(tem)) { + // son.set(V, reportSearchParam.getStartTime() + InfluxDbSqlConstant.START_TIME + "_" + reportSearchParam.getEndTime() + InfluxDbSqlConstant.END_TIME); + } else { + //台账信息 + son.set(V, finalTerminalMap.getOrDefault(tem, "/")); + } + } + } else if (v.charAt(0) == '@' && v.contains(STR_ONE)) { + //解决数据单位问题 @指标#类型@ + String replace = v.replace("@", ""); + son.set(V, unit.getOrDefault(replace, "/")); + + } + } + } + }); + }); + } + + + public static boolean isInteger(String str) { try { Integer.parseInt(str); diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/upload/impl/REvaluationDataServiceImpl.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/upload/impl/REvaluationDataServiceImpl.java index 0879e034c..84bfd0683 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/upload/impl/REvaluationDataServiceImpl.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/upload/impl/REvaluationDataServiceImpl.java @@ -13,17 +13,15 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; -import com.baomidou.mybatisplus.extension.api.R; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.njcn.common.pojo.exception.BusinessException; import com.njcn.device.pms.api.LineIntegrityDataClient; import com.njcn.device.pms.api.MonitorClient; -import com.njcn.device.pms.api.PmsMidLedgerClient; import com.njcn.device.pms.pojo.param.DataQualityDetailsParam; import com.njcn.device.pms.pojo.po.Monitor; import com.njcn.device.pq.pojo.po.RStatIntegrityD; -import com.njcn.harmonic.mapper.RStatDataVDMapper; +import com.njcn.harmonic.common.mapper.RStatDataVDMapper; import com.njcn.harmonic.mapper.upload.*; import com.njcn.harmonic.pojo.dto.upload.PqEvaluationCreateDTO; import com.njcn.harmonic.pojo.dto.upload.RDimUpDTO; @@ -35,7 +33,7 @@ import com.njcn.harmonic.pojo.po.day.RStatLimitRateDPO; import com.njcn.harmonic.pojo.po.upload.*; import com.njcn.harmonic.pojo.vo.upload.DimBusBarVO; import com.njcn.harmonic.pojo.vo.upload.UploadEvaluationDataVo; -import com.njcn.harmonic.rstatlimitrate.mapper.RStatLimitRateDMapper; +import com.njcn.harmonic.mapper.RStatLimitRateDMapper; import com.njcn.harmonic.service.upload.IEvaluationDataService; import com.njcn.harmonic.service.upload.IRUploadDataLogService; import com.njcn.system.api.DicDataFeignClient; diff --git a/pqs-harmonic/harmonic-boot/src/main/resources/file/reportModelWL.docx b/pqs-harmonic/harmonic-boot/src/main/resources/file/reportModelWL.docx new file mode 100644 index 0000000000000000000000000000000000000000..d97102cc0a164059cf18d85959b0b86c9a28275a GIT binary patch literal 79682 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 ${project.version} + + com.njcn + system-api + 1.0.0 + com.njcn cs-device-api @@ -37,4 +42,4 @@ - \ No newline at end of file + diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/ExcelRptTempMapper.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/ExcelRptTempMapper.java similarity index 85% rename from pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/ExcelRptTempMapper.java rename to pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/ExcelRptTempMapper.java index a4600aee1..dfd65fc87 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/ExcelRptTempMapper.java +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/ExcelRptTempMapper.java @@ -1,20 +1,17 @@ -package com.njcn.harmonic.mapper; +package com.njcn.harmonic.common.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.njcn.harmonic.pojo.param.ReportSearchParam; import com.njcn.harmonic.pojo.po.ExcelRptTemp; -import com.njcn.harmonic.pojo.vo.ReportTemplateVO; +import com.njcn.harmonic.common.pojo.vo.ReportTemplateVO; import com.njcn.influx.pojo.dto.StatisticalDataDTO; -import com.njcn.user.pojo.dto.DeptDTO; import com.njcn.web.pojo.param.BaseParam; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; -import java.math.BigDecimal; import java.util.List; import java.util.Map; -import java.util.Objects; /** * pqs diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/MonitorCommReportMapper.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/MonitorCommReportMapper.java new file mode 100644 index 000000000..63e78fc95 --- /dev/null +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/MonitorCommReportMapper.java @@ -0,0 +1,137 @@ +package com.njcn.harmonic.common.mapper; + +import com.njcn.harmonic.pojo.param.ReportQueryParam; +import com.njcn.harmonic.pojo.vo.ReportValue; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 谐波报告查询 + */ +public interface MonitorCommReportMapper { + /** + * 获取电流有效值 + * @return + */ + List getVirtualDataI(@Param("param") ReportQueryParam param); + + /** + * 获取电压有效值 + * @return + */ + List getVirtualDataV(@Param("param") ReportQueryParam param); + + /** + * CP95条数 + * @param param + * @return + */ + Integer getTotalCP95Day(@Param("param")ReportQueryParam param); + /** + * CP95条数 + * @param param + * @return + */ + Integer getTotalPltCP95Day(@Param("param")ReportQueryParam param); + /** + * CP95条数 + * @param param + * @return + */ + Integer getTotalPstCP95Day(@Param("param")ReportQueryParam param); + + + List getVVirtualData(@Param("param")ReportQueryParam param); + + /** + * 获取有功功率 + * @param param + * @return + */ + List getPowerP(@Param("param")ReportQueryParam param); + + /** + * 无功功率 + * @param param + * @return + */ + List getPowerQ(@Param("param")ReportQueryParam param); + + /** + * 视在功率 + * @param param + * @return + */ + List getPowerS(@Param("param")ReportQueryParam param); + + /** + * 功率因数 + * @param param + * @return + */ + List getPF(@Param("param")ReportQueryParam param); + + /** + * 短时闪变 + * @param param + * @return + */ + List getFlickerData(@Param("param")ReportQueryParam param); + + /** + * 长时闪变 + * @param param + * @return + */ + List getLFlickerData(@Param("param")ReportQueryParam param); + + /** + * 电压负偏差 + * @param param + * @return + */ + List getUVdeviationData(@Param("param")ReportQueryParam param); + + /** + * 电压正偏差 + * @param param + * @return + */ + List getLVdeviationData(@Param("param")ReportQueryParam param); + + /** + * 获取电压畸变率 + * @param param + * @return + */ + List getDistortionDataV(@Param("param")ReportQueryParam param); + + /** + * 获取电流畸变率 + * @param param + * @return + */ + List getDistortionDataI(@Param("param")ReportQueryParam param); + + /** + *频率 + * @param param + * @return + */ + List getFrequencyData(@Param("param")ReportQueryParam param); + + /** + *频率 + * @param param + * @return + */ + List getDEVFrequencyData(@Param("param")ReportQueryParam param); + + /** + * 负序电流 + * @param param + * @return + */ + List getINegData(@Param("param")ReportQueryParam param); +} diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/RStatDataHarmRateVDMapper.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/RStatDataHarmRateVDMapper.java similarity index 86% rename from pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/RStatDataHarmRateVDMapper.java rename to pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/RStatDataHarmRateVDMapper.java index 2b27ba58d..1042e4eb5 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/RStatDataHarmRateVDMapper.java +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/RStatDataHarmRateVDMapper.java @@ -1,4 +1,4 @@ -package com.njcn.harmonic.mapper; +package com.njcn.harmonic.common.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.njcn.harmonic.pojo.po.day.RStatDataHarmrateVDPO; diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/RStatDataIDMapper.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/RStatDataIDMapper.java similarity index 83% rename from pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/RStatDataIDMapper.java rename to pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/RStatDataIDMapper.java index 8b42edf67..21db5b733 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/RStatDataIDMapper.java +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/RStatDataIDMapper.java @@ -1,9 +1,7 @@ -package com.njcn.harmonic.mapper; +package com.njcn.harmonic.common.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.njcn.harmonic.pojo.po.RStatDataVD; import com.njcn.harmonic.pojo.po.day.RStatDataIDPO; -import com.njcn.harmonic.pojo.po.day.RStatDataInharmVDPO; import org.apache.ibatis.annotations.Param; import java.util.List; diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/RStatDataInharmVDMapper.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/RStatDataInharmVDMapper.java similarity index 92% rename from pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/RStatDataInharmVDMapper.java rename to pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/RStatDataInharmVDMapper.java index 7bb5e41a3..bf6fb09be 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/RStatDataInharmVDMapper.java +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/RStatDataInharmVDMapper.java @@ -1,4 +1,4 @@ -package com.njcn.harmonic.mapper; +package com.njcn.harmonic.common.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.njcn.harmonic.pojo.po.day.RStatDataInharmVDPO; diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/RStatDataVDMapper.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/RStatDataVDMapper.java similarity index 93% rename from pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/RStatDataVDMapper.java rename to pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/RStatDataVDMapper.java index 428a36e70..7efa337be 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/RStatDataVDMapper.java +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/RStatDataVDMapper.java @@ -1,8 +1,7 @@ -package com.njcn.harmonic.mapper; +package com.njcn.harmonic.common.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.njcn.harmonic.pojo.po.RStatDataVD; -import com.njcn.harmonic.pojo.po.day.RStatDataInharmVDPO; import org.apache.ibatis.annotations.Param; import java.util.List; diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/mapping/ExcelRptTempMapper.xml b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/mapping/ExcelRptTempMapper.xml similarity index 79% rename from pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/mapping/ExcelRptTempMapper.xml rename to pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/mapping/ExcelRptTempMapper.xml index 78f59a82f..a782d7fcc 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/mapping/ExcelRptTempMapper.xml +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/mapping/ExcelRptTempMapper.xml @@ -1,8 +1,8 @@ - + - select a.id, a.name, @@ -23,7 +23,7 @@ - SELECT a.id, a.NAME, @@ -40,7 +40,7 @@ a.state = 1 - SELECT DISTINCT a.id, diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/mapping/MonitorCommReportMapper.xml b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/mapping/MonitorCommReportMapper.xml new file mode 100644 index 000000000..5dd147f71 --- /dev/null +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/mapper/mapping/MonitorCommReportMapper.xml @@ -0,0 +1,467 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/pojo/dto/DeviceUnitCommDTO.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/pojo/dto/DeviceUnitCommDTO.java new file mode 100644 index 000000000..11a3cb11b --- /dev/null +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/pojo/dto/DeviceUnitCommDTO.java @@ -0,0 +1,117 @@ +package com.njcn.harmonic.common.pojo.dto; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * pqs + * + * @author cdf + * @date 2026/1/17 + */ +@Data +public class DeviceUnitCommDTO { + private static final long serialVersionUID = 1L; + + @TableId(value = "DEV_INDEX") + @ApiModelProperty(value = "终端编号") + private String devIndex; + + @TableField("UNIT_FREQUENCY") + @ApiModelProperty(value = "频率") + private String unitFrequency = "Hz"; + + @TableField("UNIT_FREQUENCY_DEV") + @ApiModelProperty(value = "频率偏差") + private String unitFrequencyDev = "Hz"; + + @TableField("PHASE_VOLTAGE") + @ApiModelProperty(value = "相电压有效值") + private String phaseVoltage = "kV"; + + @TableField("LINE_VOLTAGE") + @ApiModelProperty(value = "线电压有效值") + private String lineVoltage = "kV"; + + @TableField("VOLTAGE_DEV") + @ApiModelProperty(value = "电压上偏差") + private String voltageDev = "%"; + + @TableField("UVOLTAGE_DEV") + @ApiModelProperty(value = "电压下偏差") + private String uvoltageDev = "%"; + + @TableField("I_EFFECTIVE") + @ApiModelProperty(value = "电流有效值") + private String ieffective = "A"; + + @TableField("SINGLE_P") + @ApiModelProperty(value = "单相有功功率") + private String singleP = "kW"; + + @TableField("SINGLE_VIEW_P") + @ApiModelProperty(value = "单相视在功率") + private String singleViewP = "kVA"; + + @TableField("SINGLE_NO_P") + @ApiModelProperty(value = "单相无功功率") + private String singleNoP = "kVar"; + + @TableField("TOTAL_ACTIVE_P") + @ApiModelProperty(value = "总有功功率") + private String totalActiveP = "kW"; + + @TableField("TOTAL_VIEW_P") + @ApiModelProperty(value = "总视在功率") + private String totalViewP = "kVA"; + + @TableField("TOTAL_NO_P") + @ApiModelProperty(value = "总无功功率") + private String totalNoP = "kVar"; + + @TableField("V_FUND_EFFECTIVE") + @ApiModelProperty(value = "相(线)电压基波有效值") + private String vfundEffective = "kV"; + + @TableField("I_FUND") + @ApiModelProperty(value = "基波电流") + private String ifund = "A"; + + @TableField("FUND_ACTIVE_P") + @ApiModelProperty(value = "基波有功功率") + private String fundActiveP = "kW"; + + @TableField("FUND_NO_P") + @ApiModelProperty(value = "基波无功功率") + private String fundNoP = "kVar"; + + @TableField("V_DISTORTION") + @ApiModelProperty(value = "电压总谐波畸变率") + private String vdistortion = "%"; + + @TableField("V_HARMONIC_RATE") + @ApiModelProperty(value = "2~50次谐波电压含有率") + private String vharmonicRate = "%"; + + @TableField("I_HARMONIC") + @ApiModelProperty(value = "2~50次谐波电流有效值") + private String iharmonic = "A"; + + @TableField("P_HARMONIC") + @ApiModelProperty(value = "2~50次谐波有功功率") + private String pharmonic = "kW"; + + @TableField("I_IHARMONIC") + @ApiModelProperty(value = "0.5~49.5次间谐波电流有效值") + private String iiharmonic = "A"; + + @TableField("POSITIVE_V") + @ApiModelProperty(value = "正序电压") + private String positiveV = "kV"; + + @TableField("NO_POSITIVE_V") + @ApiModelProperty(value = "零序负序电压") + private String noPositiveV = "V"; +} diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/pojo/dto/LineDetailDataCommVO.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/pojo/dto/LineDetailDataCommVO.java new file mode 100644 index 000000000..40c51b8f5 --- /dev/null +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/pojo/dto/LineDetailDataCommVO.java @@ -0,0 +1,134 @@ +package com.njcn.harmonic.common.pojo.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +/** + * pqs + * + * @author cdf + * @date 2026/1/17 + */ +@Data +public class LineDetailDataCommVO { + + private String lineId; + + @ApiModelProperty(name = "id",value = "监测点序号") + private Integer id; + + @ApiModelProperty(name = "lineName",value = "监测点名称") + private String lineName; + + @ApiModelProperty(name = "areaName",value = "工程名称") + private String areaName; + + @ApiModelProperty(name = "gdName",value = "单位") + private String gdName; + + @ApiModelProperty(name = "bdName",value = "部门") + private String bdName; + + @ApiModelProperty(name = "scale",value = "电压等级") + private String scale; + + @ApiModelProperty(name = "manufacturer",value = "厂家") + private String manufacturer; + + @ApiModelProperty(name = "devId",value = "终端Id") + private String devId; + + @ApiModelProperty(name = "devName",value = "终端名称") + private String devName; + + @ApiModelProperty(name = "ip",value = "网络参数") + private String ip; + + @ApiModelProperty(name = "runFlag",value = "终端运行状态") + private String runFlag; + + @ApiModelProperty(name = "comFlag",value = "通讯状态") + private String comFlag; + + @ApiModelProperty(name = "loadType",value = "干扰源类型") + private String loadType; + + @ApiModelProperty(name = "businessType",value = "行业类型") + private String businessType; + + @ApiModelProperty(name = "objName",value = "监测点对象名称") + private String objName; + + @ApiModelProperty(name = "ptType",value = "接线方式") + private String ptType; + + @ApiModelProperty(name = "pt",value = "PT变比") + private String pt; + + @ApiModelProperty(name = "ct",value = "CT变比") + private String ct; + + @ApiModelProperty(name = "standardCapacity",value = "基准容量(MVA)") + private Float standardCapacity; + + @ApiModelProperty(name = "shortCapacity",value = "最小短路容量(MVA)") + private Float shortCapacity; + + @ApiModelProperty(name = "devCapacity",value = "供电设备容量(MVA)") + private Float devCapacity; + + @ApiModelProperty(name = "dealCapacity",value = "用户协议容量(MVA)") + private Float dealCapacity; + + @ApiModelProperty(name = "powerFlag",value = "电网标志(0-电网侧;1-非电网侧)") + private Integer powerFlag; + + /** + * 测量间隔(1-10分钟) + */ + @ApiModelProperty(name = "timeInterval",value = "测量间隔(1-10分钟)") + private Integer timeInterval; + + /** + * 监测点拥有者 + */ + @ApiModelProperty(name = "owner",value = "监测点拥有者") + private String owner; + + /** + * 拥有者职务 + */ + @ApiModelProperty(name = "ownerDuty",value = "拥有者职务") + private String ownerDuty; + + /** + * 拥有者联系方式 + */ + @ApiModelProperty(name = "ownerTel",value = "拥有者联系方式") + private String ownerTel; + + /** + * 接线图 + */ + @ApiModelProperty(name = "wiringDiagram",value = "接线图") + private String wiringDiagram; + @ApiModelProperty(name = "ptPhaseType",value = "监测点接线相别(0,单相,1,三相,默认三相)") + private Integer ptPhaseType; + + @ApiModelProperty(name = "投运日期") + private LocalDate loginTime; + + @ApiModelProperty(name = "最新数据时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime updateTime; + + @ApiModelProperty(name = "监测对象信息ID") + private String objId; + + @ApiModelProperty(name = "对象类型大类") + private String bigObjType; +} diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/pojo/dto/OverLimitInfoCommDTO.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/pojo/dto/OverLimitInfoCommDTO.java new file mode 100644 index 000000000..f0e1dafa0 --- /dev/null +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/pojo/dto/OverLimitInfoCommDTO.java @@ -0,0 +1,870 @@ +package com.njcn.harmonic.common.pojo.dto; + +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.Data; + +import java.io.Serializable; + +/** + * pqs + * + * @author cdf + * @date 2026/1/17 + */ +@Data +public class OverLimitInfoCommDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 监测点序号 + */ + private String id; + + /** + * 频率限值 + */ + private Float freqDev; + + /** + * 电压波动 + */ + private Float voltageFluctuation; + + /** + * 电压上偏差限值 + */ + private Float voltageDev; + + /** + * 电压下偏差限值 + */ + private Float uvoltageDev; + + /** + * 三相电压不平衡度限值 + */ + private Float ubalance; + + /** + * 短时电压不平衡度限值 + */ + private Float shortUbalance; + + /** + * 闪变限值 + */ + private Float flicker; + + /** + * 电压总谐波畸变率限值 + */ + private Float uaberrance; + + /** + * 负序电流限值 + */ + private Float iNeg; + + /** + * 2次谐波电压限值 + */ + @TableField("uharm_2") + private Float uharm2; + + /** + * 3次谐波电压限值 + */ + @TableField("uharm_3") + private Float uharm3; + + /** + * 4次谐波电压限值 + */ + @TableField("uharm_4") + private Float uharm4; + + /** + * 5次谐波电压限值 + */ + @TableField("uharm_5") + private Float uharm5; + + /** + * 6次谐波电压限值 + */ + @TableField("uharm_6") + private Float uharm6; + + /** + * 7次谐波电压限值 + */ + @TableField("uharm_7") + private Float uharm7; + + /** + * 8次谐波电压限值 + */ + @TableField("uharm_8") + private Float uharm8; + + /** + * 9次谐波电压限值 + */ + @TableField("uharm_9") + private Float uharm9; + + /** + * 10次谐波电压限值 + */ + @TableField("uharm_10") + private Float uharm10; + + /** + * 11次谐波电压限值 + */ + @TableField("uharm_11") + private Float uharm11; + + /** + * 12次谐波电压限值 + */ + @TableField("uharm_12") + private Float uharm12; + + /** + * 13次谐波电压限值 + */ + @TableField("uharm_13") + private Float uharm13; + + /** + * 14次谐波电压限值 + */ + @TableField("uharm_14") + private Float uharm14; + + /** + * 15次谐波电压限值 + */ + @TableField("uharm_15") + private Float uharm15; + + /** + * 16次谐波电压限值 + */ + @TableField("uharm_16") + private Float uharm16; + + /** + * 17次谐波电压限值 + */ + @TableField("uharm_17") + private Float uharm17; + + /** + * 18次谐波电压限值 + */ + @TableField("uharm_18") + private Float uharm18; + + /** + * 19次谐波电压限值 + */ + @TableField("uharm_19") + private Float uharm19; + + /** + * 20次谐波电压限值 + */ + @TableField("uharm_20") + private Float uharm20; + + /** + * 21次谐波电压限值 + */ + @TableField("uharm_21") + private Float uharm21; + + /** + * 22次谐波电压限值 + */ + @TableField("uharm_22") + private Float uharm22; + + /** + * 23次谐波电压限值 + */ + @TableField("uharm_23") + private Float uharm23; + + /** + * 24次谐波电压限值 + */ + @TableField("uharm_24") + private Float uharm24; + + /** + * 25次谐波电压限值 + */ + @TableField("uharm_25") + private Float uharm25; + + /** + * 2次谐波电压限值 + */ + @TableField("uharm_26") + private Float uharm26; + + /** + * 3次谐波电压限值 + */ + @TableField("uharm_27") + private Float uharm27; + + /** + * 4次谐波电压限值 + */ + @TableField("uharm_28") + private Float uharm28; + + /** + * 5次谐波电压限值 + */ + @TableField("uharm_29") + private Float uharm29; + + /** + * 6次谐波电压限值 + */ + @TableField("uharm_30") + private Float uharm30; + + /** + * 7次谐波电压限值 + */ + @TableField("uharm_31") + private Float uharm31; + + /** + * 8次谐波电压限值 + */ + @TableField("uharm_32") + private Float uharm32; + + /** + * 9次谐波电压限值 + */ + @TableField("uharm_33") + private Float uharm33; + + /** + * 10次谐波电压限值 + */ + @TableField("uharm_34") + private Float uharm34; + + /** + * 11次谐波电压限值 + */ + @TableField("uharm_35") + private Float uharm35; + + /** + * 12次谐波电压限值 + */ + @TableField("uharm_36") + private Float uharm36; + + /** + * 13次谐波电压限值 + */ + @TableField("uharm_37") + private Float uharm37; + + /** + * 14次谐波电压限值 + */ + @TableField("uharm_38") + private Float uharm38; + + /** + * 15次谐波电压限值 + */ + @TableField("uharm_39") + private Float uharm39; + + /** + * 16次谐波电压限值 + */ + @TableField("uharm_40") + private Float uharm40; + + /** + * 17次谐波电压限值 + */ + @TableField("uharm_41") + private Float uharm41; + + /** + * 18次谐波电压限值 + */ + @TableField("uharm_42") + private Float uharm42; + + /** + * 19次谐波电压限值 + */ + @TableField("uharm_43") + private Float uharm43; + + /** + * 20次谐波电压限值 + */ + @TableField("uharm_44") + private Float uharm44; + + /** + * 21次谐波电压限值 + */ + @TableField("uharm_45") + private Float uharm45; + + /** + * 22次谐波电压限值 + */ + @TableField("uharm_46") + private Float uharm46; + + /** + * 23次谐波电压限值 + */ + @TableField("uharm_47") + private Float uharm47; + + /** + * 24次谐波电压限值 + */ + @TableField("uharm_48") + private Float uharm48; + + /** + * 25次谐波电压限值 + */ + @TableField("uharm_49") + private Float uharm49; + + /** + * 50次谐波电压限值 + */ + @TableField("uharm_50") + private Float uharm50; + + + + /** + * 2次谐波电流限值 + */ + @TableField("iharm_2") + private Float iharm2; + + /** + * 3次谐波电流限值 + */ + @TableField("iharm_3") + private Float iharm3; + + /** + * 4次谐波电流限值 + */ + @TableField("iharm_4") + private Float iharm4; + + /** + * 5次谐波电流限值 + */ + @TableField("iharm_5") + private Float iharm5; + + /** + * 6次谐波电流限值 + */ + @TableField("iharm_6") + private Float iharm6; + + /** + * 7次谐波电流限值 + */ + @TableField("iharm_7") + private Float iharm7; + + /** + * 8次谐波电流限值 + */ + @TableField("iharm_8") + private Float iharm8; + + /** + * 9次谐波电流限值 + */ + @TableField("iharm_9") + private Float iharm9; + + /** + * 10次谐波电流限值 + */ + @TableField("iharm_10") + private Float iharm10; + + /** + * 11次谐波电流限值 + */ + @TableField("iharm_11") + private Float iharm11; + + /** + * 12次谐波电流限值 + */ + @TableField("iharm_12") + private Float iharm12; + + /** + * 13次谐波电流限值 + */ + @TableField("iharm_13") + private Float iharm13; + + /** + * 14次谐波电流限值 + */ + @TableField("iharm_14") + private Float iharm14; + + /** + * 15次谐波电流限值 + */ + @TableField("iharm_15") + private Float iharm15; + + /** + * 16次谐波电流限值 + */ + @TableField("iharm_16") + private Float iharm16; + + /** + * 17次谐波电流限值 + */ + @TableField("iharm_17") + private Float iharm17; + + /** + * 18次谐波电流限值 + */ + @TableField("iharm_18") + private Float iharm18; + + /** + * 19次谐波电流限值 + */ + @TableField("iharm_19") + private Float iharm19; + + /** + * 20次谐波电流限值 + */ + @TableField("iharm_20") + private Float iharm20; + + /** + * 21次谐波电流限值 + */ + @TableField("iharm_21") + private Float iharm21; + + /** + * 22次谐波电流限值 + */ + @TableField("iharm_22") + private Float iharm22; + + /** + * 23次谐波电流限值 + */ + @TableField("iharm_23") + private Float iharm23; + + /** + * 24次谐波电流限值 + */ + @TableField("iharm_24") + private Float iharm24; + + /** + * 25次谐波电流限值 + */ + @TableField("iharm_25") + private Float iharm25; + + /** + * 2次谐波电压限值 + */ + @TableField("iharm_26") + private Float iharm26; + + /** + * 3次谐波电压限值 + */ + @TableField("iharm_27") + private Float iharm27; + + /** + * 4次谐波电压限值 + */ + @TableField("iharm_28") + private Float iharm28; + + /** + * 5次谐波电压限值 + */ + @TableField("iharm_29") + private Float iharm29; + + /** + * 6次谐波电压限值 + */ + @TableField("iharm_30") + private Float iharm30; + + /** + * 7次谐波电压限值 + */ + @TableField("iharm_31") + private Float iharm31; + + /** + * 8次谐波电压限值 + */ + @TableField("iharm_32") + private Float iharm32; + + /** + * 9次谐波电压限值 + */ + @TableField("iharm_33") + private Float iharm33; + + /** + * 10次谐波电压限值 + */ + @TableField("iharm_34") + private Float iharm34; + + /** + * 11次谐波电压限值 + */ + @TableField("iharm_35") + private Float iharm35; + + /** + * 12次谐波电压限值 + */ + @TableField("iharm_36") + private Float iharm36; + + /** + * 13次谐波电压限值 + */ + @TableField("iharm_37") + private Float iharm37; + + /** + * 14次谐波电压限值 + */ + @TableField("iharm_38") + private Float iharm38; + + /** + * 15次谐波电压限值 + */ + @TableField("iharm_39") + private Float iharm39; + + /** + * 16次谐波电压限值 + */ + @TableField("iharm_40") + private Float iharm40; + + /** + * 17次谐波电压限值 + */ + @TableField("iharm_41") + private Float iharm41; + + /** + * 18次谐波电压限值 + */ + @TableField("iharm_42") + private Float iharm42; + + /** + * 19次谐波电压限值 + */ + @TableField("iharm_43") + private Float iharm43; + + /** + * 20次谐波电压限值 + */ + @TableField("iharm_44") + private Float iharm44; + + /** + * 21次谐波电压限值 + */ + @TableField("iharm_45") + private Float iharm45; + + /** + * 22次谐波电压限值 + */ + @TableField("iharm_46") + private Float iharm46; + + /** + * 23次谐波电压限值 + */ + @TableField("iharm_47") + private Float iharm47; + + /** + * 24次谐波电压限值 + */ + @TableField("iharm_48") + private Float iharm48; + + /** + * 25次谐波电压限值 + */ + @TableField("iharm_49") + private Float iharm49; + + /** + * 50次谐波电压限值 + */ + @TableField("iharm_50") + private Float iharm50; + + + + /** + * 0.5次间谐波电压限值 + */ + @TableField("inuharm_1") + private Float inuharm1; + + /** + * 1.5次间谐波电压限值 + */ + @TableField("inuharm_2") + private Float inuharm2; + + /** + * 2.5次间谐波电压限值 + */ + @TableField("inuharm_3") + private Float inuharm3; + + /** + * 3.5次间谐波电压限值 + */ + @TableField("inuharm_4") + private Float inuharm4; + + /** + * 4.5次间谐波电压限值 + */ + @TableField("inuharm_5") + private Float inuharm5; + + /** + * 5.5次间谐波电压限值 + */ + @TableField("inuharm_6") + private Float inuharm6; + + /** + * 6.5次间谐波电压限值 + */ + @TableField("inuharm_7") + private Float inuharm7; + + /** + * 7.5次间谐波电压限值 + */ + @TableField("inuharm_8") + private Float inuharm8; + + /** + * 8.5次间谐波电压限值 + */ + @TableField("inuharm_9") + private Float inuharm9; + + /** + * 9.5次间谐波电压限值 + */ + @TableField("inuharm_10") + private Float inuharm10; + + /** + * 10.5次间谐波电压限值 + */ + @TableField("inuharm_11") + private Float inuharm11; + + /** + * 11.5次间谐波电压限值 + */ + @TableField("inuharm_12") + private Float inuharm12; + + /** + * 12.5次间谐波电压限值 + */ + @TableField("inuharm_13") + private Float inuharm13; + + /** + * 13.5次间谐波电压限值 + */ + @TableField("inuharm_14") + private Float inuharm14; + + /** + * 14.5次间谐波电压限值 + */ + @TableField("inuharm_15") + private Float inuharm15; + + /** + * 15.5次间谐波电压限值 + */ + @TableField("inuharm_16") + private Float inuharm16; + + public OverLimitInfoCommDTO(){} + + + public void buildIHarm(Float[] iHarmTem){ + this.iharm2= iHarmTem[0]; + this.iharm4= iHarmTem[2]; + this.iharm6= iHarmTem[4]; + this.iharm8= iHarmTem[6]; + this.iharm10= iHarmTem[8]; + this.iharm12= iHarmTem[10]; + this.iharm14= iHarmTem[12]; + this.iharm16= iHarmTem[14]; + this.iharm18= iHarmTem[16]; + this.iharm20= iHarmTem[18]; + this.iharm22= iHarmTem[20]; + this.iharm24= iHarmTem[22]; + this.iharm26= iHarmTem[24]; + this.iharm28= iHarmTem[26]; + this.iharm30= iHarmTem[28]; + this.iharm32= iHarmTem[30]; + this.iharm34= iHarmTem[32]; + this.iharm36= iHarmTem[34]; + this.iharm38= iHarmTem[36]; + this.iharm40= iHarmTem[38]; + this.iharm42= iHarmTem[40]; + this.iharm44= iHarmTem[42]; + this.iharm46= iHarmTem[44]; + this.iharm48= iHarmTem[46]; + this.iharm50= iHarmTem[48]; + + + + this.iharm3= iHarmTem[1]; + this.iharm5= iHarmTem[3]; + this.iharm7= iHarmTem[5]; + this.iharm9= iHarmTem[7]; + this.iharm11= iHarmTem[9]; + this.iharm13= iHarmTem[11]; + this.iharm15= iHarmTem[13]; + this.iharm17= iHarmTem[15]; + this.iharm19= iHarmTem[17]; + this.iharm21= iHarmTem[19]; + this.iharm23= iHarmTem[21]; + this.iharm25= iHarmTem[23]; + this.iharm27= iHarmTem[25]; + this.iharm29= iHarmTem[27]; + this.iharm31= iHarmTem[29]; + this.iharm33= iHarmTem[31]; + this.iharm35= iHarmTem[33]; + this.iharm37= iHarmTem[35]; + this.iharm39= iHarmTem[37]; + this.iharm41= iHarmTem[39]; + this.iharm43= iHarmTem[41]; + this.iharm45= iHarmTem[43]; + this.iharm47= iHarmTem[45]; + this.iharm49= iHarmTem[47]; + } + + public void buildUharm(Float resultEven,Float resultOdd){ + this.uharm2=resultEven; + this.uharm4=resultEven; + this.uharm6=resultEven; + this.uharm8=resultEven; + this.uharm10=resultEven; + this.uharm12=resultEven; + this.uharm14=resultEven; + this.uharm16=resultEven; + this.uharm18=resultEven; + this.uharm20=resultEven; + this.uharm22=resultEven; + this.uharm24=resultEven; + this.uharm26=resultEven; + this.uharm28=resultEven; + this.uharm30=resultEven; + this.uharm32=resultEven; + this.uharm34=resultEven; + this.uharm36=resultEven; + this.uharm38=resultEven; + this.uharm40=resultEven; + this.uharm42=resultEven; + this.uharm44=resultEven; + this.uharm46=resultEven; + this.uharm48=resultEven; + this.uharm50=resultEven; + + + this.uharm3=resultOdd; + this.uharm5=resultOdd; + this.uharm7=resultOdd; + this.uharm9=resultOdd; + this.uharm11=resultOdd; + this.uharm13=resultOdd; + this.uharm15=resultOdd; + this.uharm17=resultOdd; + this.uharm19=resultOdd; + this.uharm21=resultOdd; + this.uharm23=resultOdd; + this.uharm25=resultOdd; + this.uharm27=resultOdd; + this.uharm29=resultOdd; + this.uharm31=resultOdd; + this.uharm33=resultOdd; + this.uharm35=resultOdd; + this.uharm37=resultOdd; + this.uharm39=resultOdd; + this.uharm41=resultOdd; + this.uharm43=resultOdd; + this.uharm45=resultOdd; + this.uharm47=resultOdd; + this.uharm49=resultOdd; + } + + +} diff --git a/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/vo/ReportTemplateVO.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/pojo/vo/ReportTemplateVO.java similarity index 92% rename from pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/vo/ReportTemplateVO.java rename to pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/pojo/vo/ReportTemplateVO.java index c7b7e7dc3..d3ec1d4f9 100644 --- a/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/vo/ReportTemplateVO.java +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/pojo/vo/ReportTemplateVO.java @@ -1,4 +1,4 @@ -package com.njcn.harmonic.pojo.vo; +package com.njcn.harmonic.common.pojo.vo; import com.njcn.db.bo.BaseEntity; import lombok.Data; diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/CustomReportTableService.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/CustomReportTableService.java new file mode 100644 index 000000000..4dd6a785f --- /dev/null +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/CustomReportTableService.java @@ -0,0 +1,25 @@ +package com.njcn.harmonic.common.service; + +import com.njcn.harmonic.pojo.param.ReportSearchParam; + +import javax.servlet.http.HttpServletResponse; + +/** + * pqs + * + * @author cdf + * @date 2026/1/15 + */ +public interface CustomReportTableService { + + + /** + * 替换报表数据并返回 + * + * @param reportSearchParam 请求参数 + * @param response + * @author qijian + * @date 2022/10/18 + */ + void getCustomReport(ReportSearchParam reportSearchParam, HttpServletResponse response); +} diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/MonitorCommReportService.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/MonitorCommReportService.java new file mode 100644 index 000000000..645e39127 --- /dev/null +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/MonitorCommReportService.java @@ -0,0 +1,96 @@ +package com.njcn.harmonic.common.service; + +import com.njcn.harmonic.pojo.param.ReportQueryParam; +import com.njcn.harmonic.pojo.vo.ReportValue; + +import java.util.List; + +/** + * 谐波报告 + */ +public interface MonitorCommReportService { + + /** + * 限值 + * @param param + * @return + */ + /* OverLimitInfo getOverLimitData(ReportQueryParam param); +*/ + /** + * 基波增幅 + * @param param + * @return + */ + List getVirtualData(ReportQueryParam param); + + /** + * 功率 + * @param param + * @return + */ + List getPowerData(ReportQueryParam param); + + /** + * 闪变 + * @param param + * @return + */ + List getFlickerData(ReportQueryParam param); + + /** + * 电压偏差 + * @param param + * @return + */ + List getVdeviation(ReportQueryParam param); + + /** + * 畸变率 + * @param param + * @return + */ + List getDistortionData(ReportQueryParam param); + + /** + * 频率 + * @param param + * @return + */ + List getFrequencyData(ReportQueryParam param); + + /** + * 三相不平衡 + * @param param + * @return + */ + List getThreephase(ReportQueryParam param); + + /** + * 谐波电流 + * @param param + * @return + */ + List getICurrent(ReportQueryParam param); + + /** + * 谐波电压 + * @param param + * @return + */ + List getVoltageRate(ReportQueryParam param); + + /** + * 间谐波 + * @param param + * @return + */ + List getInharmVeRate(ReportQueryParam param); + + /** + * 负序电流 + * @param param + * @return + */ + List getINegDataRate(ReportQueryParam param); +} diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/MonitorHarmonicReportService.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/MonitorHarmonicReportService.java new file mode 100644 index 000000000..7bf3f873a --- /dev/null +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/MonitorHarmonicReportService.java @@ -0,0 +1,29 @@ +package com.njcn.harmonic.common.service; + +import com.njcn.harmonic.common.pojo.dto.DeviceUnitCommDTO; +import com.njcn.harmonic.common.pojo.dto.LineDetailDataCommVO; +import com.njcn.harmonic.common.pojo.dto.OverLimitInfoCommDTO; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; + +/** + * pqs + * + * @author cdf + * @date 2026/1/17 + */ +public interface MonitorHarmonicReportService { + + void exportWorld(HttpServletResponse response, + String startTime, + String endTime, + Integer type, + String lineIndex, + String name, + String reportNumber, + String crmName, + Boolean isUrl, + MultipartFile file, + LineDetailDataCommVO lineDto, OverLimitInfoCommDTO overLimitData, DeviceUnitCommDTO deviceUnit); +} diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/CustomReportTableServiceImpl.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/CustomReportTableServiceImpl.java new file mode 100644 index 000000000..c0e456382 --- /dev/null +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/CustomReportTableServiceImpl.java @@ -0,0 +1,788 @@ +package com.njcn.harmonic.common.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.date.TimeInterval; +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.text.StrPool; +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONConfig; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONTokener; +import com.baomidou.dynamic.datasource.annotation.DS; +import com.baomidou.mybatisplus.extension.toolkit.SqlRunner; +import com.njcn.common.pojo.enums.response.CommonResponseEnum; +import com.njcn.common.pojo.exception.BusinessException; +import com.njcn.csdevice.api.CsCommTerminalFeignClient; +import com.njcn.device.biz.commApi.CommTerminalGeneralClient; +import com.njcn.device.biz.pojo.po.PqsDeviceUnit; +import com.njcn.harmonic.enums.HarmonicResponseEnum; +import com.njcn.harmonic.pojo.dto.ReportTemplateDTO; +import com.njcn.harmonic.pojo.param.ReportSearchParam; +import com.njcn.harmonic.pojo.po.ExcelRptTemp; +import com.njcn.harmonic.common.mapper.ExcelRptTempMapper; +import com.njcn.harmonic.common.service.CustomReportTableService; +import com.njcn.influx.constant.InfluxDbSqlConstant; +import com.njcn.influx.pojo.constant.InfluxDBTableConstant; +import com.njcn.oss.enums.OssResponseEnum; +import com.njcn.oss.utils.FileStorageUtil; +import com.njcn.system.api.DicDataFeignClient; +import com.njcn.system.api.EpdFeignClient; +import com.njcn.system.enums.DicDataEnum; +import com.njcn.system.enums.DicDataTypeEnum; +import com.njcn.system.pojo.po.DictData; +import com.njcn.system.pojo.po.EleEpdPqd; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; +import org.apache.tomcat.util.http.fileupload.IOUtils; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.*; +import java.util.concurrent.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * pqs + * + * @author cdf + * @date 2026/1/15 + */ +@Service +@RequiredArgsConstructor +@Slf4j +@DS("sjzx") +public class CustomReportTableServiceImpl implements CustomReportTableService { + + private final ExcelRptTempMapper excelRptTempMapper; + + private final EpdFeignClient epdFeignClient; + + private final FileStorageUtil fileStorageUtil; + + private final DicDataFeignClient dicDataFeignClient; + + + private final CommTerminalGeneralClient commTerminalGeneralClient; + + private final CsCommTerminalFeignClient csCommTerminalFeignClient; + + private final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1); + + private final String CELL_DATA = "celldata"; + private final String V = "v"; + private final String STR_ONE = "#"; + private final String STR_TWO = "$"; + private final String STR_THREE = "&"; + private final String STR_FOUR = "%"; + private final String UVOLTAGE_DEV = "UVOLTAGE_DEV"; + private final String VOLTAGE_DEV = "VOLTAGE_DEV"; + + @Override + public void getCustomReport(ReportSearchParam reportSearchParam, HttpServletResponse response) { + TimeInterval timeInterval = new TimeInterval(); + ExcelRptTemp excelRptTemp = excelRptTempMapper.selectById(reportSearchParam.getTempId()); + if (Objects.isNull(excelRptTemp)) { + throw new BusinessException(HarmonicResponseEnum.CUSTOM_REPORT_ACTIVE); + } + if (Objects.isNull(reportSearchParam.getCustomType())) { + //通用报表 + analyzeReport(reportSearchParam, excelRptTemp, response); + + log.info("报表执行时间{}秒", timeInterval.intervalSecond()); + } + } + + + /** + * 处理 + * + * @author cdf + * @date 2023/10/8 + */ + + private void analyzeReport(ReportSearchParam reportSearchParam, ExcelRptTemp excelRptTemp, HttpServletResponse response) { + //定义一个线程集合 + List> futures = new ArrayList<>(); + //指标 + List reportTemplateDTOList = new ArrayList<>(); + //限值 + List reportLimitList = new ArrayList<>(); + //台账 + List terminalList = new ArrayList<>(); + JSONArray jsonArray; + try (InputStream fileStream = fileStorageUtil.getFileStream(excelRptTemp.getContent())) { + jsonArray = new JSONArray(new JSONTokener(fileStream, new JSONConfig())); + parseTemplate(jsonArray, reportTemplateDTOList, reportLimitList, terminalList); + } catch (Exception e) { + if(e instanceof BusinessException){ + throw new BusinessException(e.getMessage()); + }else { + throw new BusinessException(HarmonicResponseEnum.CUSTOM_REPORT_JSON); + } + } + //查询不分相别的指标 + DictData dictData = dicDataFeignClient.getDicDataByCodeAndType(DicDataEnum.EPD.getCode(), DicDataTypeEnum.CS_DATA_TYPE.getCode()).getData(); + if(Objects.isNull(dictData)){ + throw new BusinessException(CommonResponseEnum.FAIL,"字典类型模板缺少!"); + } + + + DictData epdDic = dicDataFeignClient.getDicDataByCodeAndType(DicDataEnum.EPD.getCode(),DicDataTypeEnum.CS_DATA_TYPE.getCode()).getData(); + List eleEpdPqdList= epdFeignClient.dictMarkByDataType(epdDic.getId()).getData(); + eleEpdPqdList = eleEpdPqdList.stream().filter(it->"T".equals(it.getPhase())||"M".equals(it.getPhase())).collect(Collectors.toList()); + List noPhaseList = eleEpdPqdList.stream().filter(it->StrUtil.isNotBlank(it.getOtherName())).map(it->it.getOtherName().toUpperCase()).collect(Collectors.toList()); + + //处理指标是否合格 + reportLimitList = new LinkedHashSet<>(reportLimitList).stream().sorted(Comparator.comparing(ReportTemplateDTO::getItemName)).collect(Collectors.toList()); + Map limitMap = overLimitDeal(reportLimitList, reportSearchParam); + //存放限值指标的map + Map limitTargetMapX = reportLimitList.stream().collect(Collectors.toMap(ReportTemplateDTO::getItemName, Function.identity())); + + List endList = new CopyOnWriteArrayList<>(); + if (CollUtil.isNotEmpty(reportTemplateDTOList)) { + //开始组织sql + reportTemplateDTOList = new LinkedHashSet<>(reportTemplateDTOList).stream().sorted(Comparator.comparing(ReportTemplateDTO::getItemName)).collect(Collectors.toList()); + Map> classMap = reportTemplateDTOList.stream().collect(Collectors.groupingBy(ReportTemplateDTO::getResourceId)); + //定义存放越限指标的map + Map assNoPassMap = new HashMap<>(); + classMap.forEach((classKey, templateValue) -> { + Map> valueTypeMap = templateValue.stream().collect(Collectors.groupingBy(ReportTemplateDTO::getStatMethod)); + //每张表开启一个独立线程查询 + futures.add(executorService.submit(() -> { + //avg.max,min,cp95 + valueTypeMap.forEach((valueTypeKey, valueTypeVal) -> { + //相别分组 + Map> phaseMap = valueTypeVal.stream().collect(Collectors.groupingBy(ReportTemplateDTO::getPhase)); + phaseMap.forEach((phaseKey, phaseVal) -> { + StringBuilder sql = new StringBuilder(InfluxDbSqlConstant.SELECT); + if (InfluxDbSqlConstant.MAX.equalsIgnoreCase(valueTypeKey)) { + assSqlByMysql(phaseVal, sql, endList, InfluxDbSqlConstant.MAX, reportSearchParam, limitTargetMapX, limitMap, assNoPassMap,noPhaseList); + } else if (InfluxDbSqlConstant.MIN.equalsIgnoreCase(valueTypeKey)) { + assSqlByMysql(phaseVal, sql, endList, InfluxDbSqlConstant.MIN, reportSearchParam, limitTargetMapX, limitMap, assNoPassMap,noPhaseList); + } else if (InfluxDbSqlConstant.AVG_WEB.equalsIgnoreCase(valueTypeKey)) { + assSqlByMysql(phaseVal, sql, endList, InfluxDbSqlConstant.AVG_WEB, reportSearchParam, limitTargetMapX, limitMap, assNoPassMap,noPhaseList); + } else if (InfluxDbSqlConstant.CP95.equalsIgnoreCase(valueTypeKey)) { + assSqlByMysql(phaseVal, sql, endList, InfluxDbSqlConstant.CP95, reportSearchParam, limitTargetMapX, limitMap, assNoPassMap,noPhaseList); + } + + }); + }); + })); + + }); + + // 等待所有任务完成 + for (Future future : futures) { + try { + future.get(); // 这会阻塞直到任务完成或抛出异常 + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + log.error("自定义报表多线程查询流程出错!错误信息{}",e.getMessage()); + } + } + + //处理指标最终判定合格还是不合格 + dealTargetResult(assNoPassMap, limitTargetMapX, endList); + } + resultAssemble(endList,reportSearchParam,terminalList,jsonArray); + //导出自定义报表 + downReport(jsonArray, response); + } + + + + /** + * 解析模板 + * @author cdf + * @date 2023/10/20 + */ + private void parseTemplate(JSONArray jsonArray, List reportTemplateDTOList, List reportLimitList, List terminalList) { + try { + //通过文件服务器获取 + jsonArray.forEach(item -> { + JSONObject jsonObject = (JSONObject) item; + JSONArray itemArr = (JSONArray) jsonObject.get(CELL_DATA); + itemArr.forEach((it) -> { + if (Objects.nonNull(it) && !"null".equals(it.toString())) { + //获取到1列 + JSONObject data = (JSONObject) it; + JSONObject son = (JSONObject) data.get(V); + if (son.containsKey(V)) { + String v = son.getStr(V); + //数据格式:$HA[_25]#B#max#classId$ 或 $HA[_25]#max#classId$ + if (v.charAt(0) == '$' && v.contains(STR_ONE)) { + //剔除前后$ + v = v.replace(STR_TWO, ""); + //封装ReportTemplateDTO + ReportTemplateDTO reportTemplateDTO = new ReportTemplateDTO(); + reportTemplateDTO.setItemName(v.toUpperCase()); + //根据#分割数据 + String[] vItem = v.split(STR_ONE); + if (vItem.length == 5) { + //$HA[_25]#B#max#classId$ + reportTemplateDTO.setTemplateName(vItem[0].toUpperCase()); + reportTemplateDTO.setPhase(vItem[1].substring(0, 1).toUpperCase()); + reportTemplateDTO.setStatMethod(vItem[2].toUpperCase()); + reportTemplateDTO.setResourceId(vItem[3].toUpperCase()); + reportTemplateDTO.setLimitName(vItem[4].toUpperCase()); + } else if (vItem.length == 4) { + //$HA[_25]#max#classId$ + reportTemplateDTO.setTemplateName(vItem[0].toUpperCase()); + reportTemplateDTO.setPhase("T"); + reportTemplateDTO.setStatMethod(vItem[1].toUpperCase()); + reportTemplateDTO.setResourceId(vItem[2].toUpperCase()); + reportTemplateDTO.setLimitName(vItem[3].toUpperCase()); + } + + reportTemplateDTOList.add(reportTemplateDTO); + } else if (v.charAt(0) == '%' && v.contains(STR_ONE)) { + //封装指标结论ReportTemplateDTO + ReportTemplateDTO reportTemplateDTO = new ReportTemplateDTO(); + v = v.replace(STR_FOUR, ""); + reportTemplateDTO.setItemName(v.toUpperCase()); + //根据#分割数据 + String[] vItem = v.split(STR_ONE); + if (vItem.length == 3) { + reportTemplateDTO.setTemplateName(vItem[0].toUpperCase()); + reportTemplateDTO.setStatMethod(vItem[1].toUpperCase()); + reportTemplateDTO.setResourceId(vItem[2].toUpperCase()); + } + reportLimitList.add(reportTemplateDTO); + } else if (v.charAt(0) == '&') { + //封装ReportTemplateDTO + ReportTemplateDTO reportTemplateDTO = new ReportTemplateDTO(); + v = v.replace(STR_THREE, ""); + reportTemplateDTO.setItemName(v.toUpperCase()); + reportTemplateDTO.setTemplateName(v.toUpperCase()); + terminalList.add(reportTemplateDTO); + } + } + } + }); + }); + } catch (Exception e) { + throw new BusinessException(HarmonicResponseEnum.CUSTOM_REPORT_JSON); + } + } + + + /** + * 获取测点限值 + * + * @author cdf + * @date 2023/10/23 + */ + private Map overLimitDeal(List reportLimitList, ReportSearchParam + reportSearchParam) { + Map limitMap = new HashMap<>(); + if (CollUtil.isNotEmpty(reportLimitList)) { + StringBuilder sql = new StringBuilder(InfluxDbSqlConstant.SELECT); + for (int i = 0; i < reportLimitList.size(); i++) { + if (i == reportLimitList.size() - 1) { + sql.append(UVOLTAGE_DEV).append(StrUtil.COMMA); + sql.append(reportLimitList.get(i).getTemplateName()).append(StrUtil.C_SPACE); + } else { + sql.append(reportLimitList.get(i).getTemplateName()).append(StrUtil.COMMA); + } + } + + sql.append(InfluxDbSqlConstant.FROM).append(reportLimitList.get(0).getResourceId()).append(InfluxDbSqlConstant.WHERE).append("id ='").append(reportSearchParam.getLineId()).append("'"); + limitMap = excelRptTempMapper.dynamicSqlMap(sql.toString()); + if (Objects.isNull(limitMap)) { + throw new BusinessException("当前报表测点限值缺失!"); + } + + for (ReportTemplateDTO item : reportLimitList) { + if (limitMap.containsKey(item.getTemplateName())) { + + if(item.getTemplateName().equalsIgnoreCase(VOLTAGE_DEV)){ + item.setLowValue(limitMap.get(UVOLTAGE_DEV).toString()); + } + item.setValue(limitMap.get(item.getTemplateName()).toString()); + } + } + } + limitMap = convertKeysToUpperCase(limitMap); + return limitMap; + } + + /** + * 报告下载 + */ + private void downReport(JSONArray jsonArray, HttpServletResponse response) { + InputStream reportStream = IoUtil.toStream(jsonArray.toString(), CharsetUtil.UTF_8); + response.setContentType("application/octet-stream;charset=UTF-8"); + response.setHeader("Content-Disposition", "attachment;filename=" + "aa"); + OutputStream toClient = null; + try { + toClient = new BufferedOutputStream(response.getOutputStream()); + //通过IOUtils对接输入输出流,实现文件下载 + IOUtils.copy(reportStream, toClient); + toClient.flush(); + } catch (Exception e) { + throw new BusinessException(OssResponseEnum.DOWNLOAD_FILE_STREAM_ERROR); + } finally { + IOUtils.closeQuietly(reportStream); + IOUtils.closeQuietly(toClient); + } + } + + + /** + * 对多测点数据进行计算求出一组数据 + * @param method + * @param allList + * @return + */ + private Map dealResultMap(String method, List> allList) { + Map resultMap = new HashMap<>(); + // 遍历列表中的每个Map + if (method.equals(InfluxDbSqlConstant.MIN)) { + for (Map map : allList) { + // 遍历当前Map的键值对 + for (Map.Entry entry : map.entrySet()) { + String key = entry.getKey(); + if (Objects.nonNull(entry.getValue()) && !key.equals("time")) { + double value = (double) entry.getValue(); + // 检查结果Map中是否已包含该键 + if (!resultMap.containsKey(key) || (double) resultMap.get(key) > value) { + // 如果不包含,或当前值更大,则更新结果Map + resultMap.put(key, value); + } + } + } + } + } else if (method.equals(InfluxDbSqlConstant.MAX) || method.equals(InfluxDbSqlConstant.PERCENTILE)) { + for (Map map : allList) { + // 遍历当前Map的键值对 + for (Map.Entry entry : map.entrySet()) { + String key = entry.getKey(); + if (Objects.nonNull(entry.getValue()) && !key.equals("time")) { + double value = (double) entry.getValue(); + // 检查结果Map中是否已包含该键 + if (!resultMap.containsKey(key) || (double) resultMap.get(key) < value) { + // 如果不包含,或当前值更大,则更新结果Map + resultMap.put(key, value); + } + } + } + } + } else if (method.equals(InfluxDbSqlConstant.AVG)) { + Map sumMap = new HashMap<>(); + Map countMap = new HashMap<>(); + // 遍历列表中的每个Map + for (Map map : allList) { + // 遍历当前Map的键值对 + for (Map.Entry entry : map.entrySet()) { + String key = entry.getKey(); + if (Objects.nonNull(entry.getValue()) && !key.equals("time")) { + double value = (double) entry.getValue(); + + // 更新累计和 + sumMap.put(key, sumMap.getOrDefault(key, 0.0) + value); + // 更新计数 + countMap.put(key, countMap.getOrDefault(key, 0) + 1); + } + } + } + + // 计算平均值并存储到结果Map中 + for (String key : sumMap.keySet()) { + double sum = sumMap.get(key); + int count = countMap.get(key); + double average = BigDecimal.valueOf(sum / count).setScale(3, RoundingMode.HALF_UP).doubleValue(); + resultMap.put(key, average); + } + } + + return resultMap; + } + + + + /** + * 处理指标超标结论 + */ + private void dealTargetResult + (Map assNoPassMap, Map limitTargetMapX, List endList) { + assNoPassMap.forEach((key, val) -> { + limitTargetMapX.remove(key); + if ("Freq_Dev".toUpperCase().equals(val.getTemplateName())) { + val.setValue("±" + val.getValue()); + } + + String expend = ""; + if(Objects.nonNull(val.getLowValue())){ + expend = val.getLowValue()+","; + } + if (val.getOverLimitFlag() == 1) { + val.setValue("不合格 (" + expend+val.getValue() + ")"); + } else { + val.setValue("合格 (" + expend+val.getValue() + ")"); + } + endList.add(val); + }); + + limitTargetMapX.forEach((key, val) -> { + if (Objects.isNull(val.getOverLimitFlag())) { + val.setValue("/"); + } else { + val.setValue("合格"); + } + endList.add(val); + }); + } + + + /** + * @param data 同类型的cell模板 + * @param sql 单个cell模板 + * @param endList 用于返回最终组装好的数据,类似data + * @param limitMap 指标是否合格模板 + * @param assNoPassMap 用于存储不合格的指标 + * @date 2023/10/20 + */ + + private void assSqlByMysql(List data, StringBuilder sql, List endList, String method, ReportSearchParam reportSearchParam, Map limitMap, Map overLimitMap, Map assNoPassMap,List noPhaseList) { + //sql拼接示例:select MAX(IHA2) as IHA2 from power_quality_data where Phase = 'A' and LineId='1324564568' and Stat_Method='max' tz('Asia/Shanghai') + if (InfluxDbSqlConstant.CP95.equals(method)) { + for (int i = 0; i < data.size(); i++) { + if (i == data.size() - 1) { + sql.append(InfluxDbSqlConstant.MAX) + .append(InfluxDbSqlConstant.LBK) + .append(data.get(i).getTemplateName()) + .append(InfluxDbSqlConstant.RBK) + .append(InfluxDbSqlConstant.AS) + .append("\""+data.get(i).getItemName()+"\""); + } else { + sql.append(InfluxDbSqlConstant.MAX) + .append(InfluxDbSqlConstant.LBK) + .append(data.get(i).getTemplateName()) + .append(InfluxDbSqlConstant.RBK) + .append(InfluxDbSqlConstant.AS) + .append("\""+data.get(i).getItemName()+"\"").append(StrUtil.COMMA); + } + } + } else { + for (int i = 0; i < data.size(); i++) { + if (i == data.size() - 1) { + sql.append(method) + .append(InfluxDbSqlConstant.LBK) + .append(data.get(i).getTemplateName()) + .append(InfluxDbSqlConstant.RBK) + .append(InfluxDbSqlConstant.AS) + .append("\""+data.get(i).getItemName()+"\""); + } else { + sql.append(method) + .append(InfluxDbSqlConstant.LBK) + .append(data.get(i).getTemplateName()) + .append(InfluxDbSqlConstant.RBK) + .append(InfluxDbSqlConstant.AS) + .append("\""+data.get(i).getItemName()+"\"").append(StrUtil.COMMA); + } + } + + } + + //拼接表名 + sql.append(StrPool.C_SPACE) + .append(InfluxDbSqlConstant.FROM) + .append(data.get(0).getResourceId()); + + + sql.append(InfluxDbSqlConstant.WHERE) + .append(InfluxDBTableConstant.LINE_ID) + .append(InfluxDbSqlConstant.EQ) + .append(InfluxDbSqlConstant.QM) + .append(reportSearchParam.getLineId()) + .append(InfluxDbSqlConstant.QM); + //相别特殊处理 + if (!InfluxDBTableConstant.NO_PHASE.equals(data.get(0).getPhase())) { + sql.append(InfluxDbSqlConstant.AND) + .append(InfluxDBTableConstant.PHASIC_TYPE) + .append(InfluxDbSqlConstant.EQ) + .append(InfluxDbSqlConstant.QM) + .append(data.get(0).getPhase()) + .append(InfluxDbSqlConstant.QM); + } + + sql.append(InfluxDbSqlConstant.AND) + .append(InfluxDBTableConstant.VALUE_TYPE) + .append(InfluxDbSqlConstant.EQ) + .append(InfluxDbSqlConstant.QM) + .append(data.get(0).getStatMethod()) + .append(InfluxDbSqlConstant.QM); + + + //频率和频率偏差仅统计T相 + if (noPhaseList.contains(data.get(0).getTemplateName())) { + if(data.get(0).getTemplateName().equalsIgnoreCase("v_unbalance")){ + System.out.println(44); + } + sql.append(InfluxDbSqlConstant.AND) + .append(InfluxDBTableConstant.PHASIC_TYPE) + .append(InfluxDbSqlConstant.EQ) + .append(InfluxDbSqlConstant.QM) + .append(InfluxDBTableConstant.PHASE_TYPE_T) + .append(InfluxDbSqlConstant.QM); + } + //时间范围处理 + sql.append(InfluxDbSqlConstant.AND) + .append(InfluxDbSqlConstant.TIME).append(InfluxDbSqlConstant.GE).append(InfluxDbSqlConstant.QM).append(reportSearchParam.getStartTime()).append(InfluxDbSqlConstant.START_TIME).append(InfluxDbSqlConstant.QM) + .append(InfluxDbSqlConstant.AND) + .append(InfluxDbSqlConstant.TIME).append(InfluxDbSqlConstant.LT).append(InfluxDbSqlConstant.QM).append(reportSearchParam.getEndTime()).append(InfluxDbSqlConstant.END_TIME).append(InfluxDbSqlConstant.QM); + + System.out.println(sql); + + List> mapList = SqlRunner.DEFAULT.selectList(sql.toString()); + if (CollUtil.isEmpty(mapList) || Objects.isNull(mapList.get(0))) { + data = data.stream().peek(item -> item.setValue("/")).collect(Collectors.toList()); + } else { + //兼容达梦数据库方法 + Map map = convertKeysToUpperCase(mapList.get(0)); + for (ReportTemplateDTO item : data) { + if (map.containsKey(item.getItemName())) { + double v = Double.parseDouble(map.get(item.getItemName()).toString()); + item.setValue(String.format("%.3f", v)); + if (overLimitMap.containsKey(item.getLimitName())) { + Float tagVal = overLimitMap.get(item.getLimitName()); + + if(item.getLimitName().equalsIgnoreCase(UVOLTAGE_DEV)){ + //对电压偏差特殊处理 + Float tagVal_U = overLimitMap.get(UVOLTAGE_DEV); + if (v > tagVal || v tagVal) { + item.setOverLimitFlag(1); + } else { + item.setOverLimitFlag(0); + } + } + } + + //判断是否越限 + if (!limitMap.isEmpty()) { + String key = item.getLimitName() + STR_ONE + item.getStatMethod() + "#PQ_OVERLIMIT"; + if (limitMap.containsKey(key)) { + ReportTemplateDTO tem = limitMap.get(key); + double limitVal = Double.parseDouble(tem.getValue()); + + if(VOLTAGE_DEV.equalsIgnoreCase(tem.getLimitName())){ + //针对电压偏差特殊处理 + double limitLowVal = Double.parseDouble(tem.getLowValue()); + + if (v > limitVal || v limitVal) { + tem.setOverLimitFlag(1); + assNoPassMap.put(key, tem); + } else if (!assNoPassMap.containsKey(key)) { + tem.setOverLimitFlag(0); + assNoPassMap.put(key, tem); + } + } + } + } + } else { + item.setValue("/"); + } + } + } + endList.addAll(data); + } + + + /** + * 数据单位信息 + * + * @param reportSearchParam + * @return + */ + private Map unitMap(ReportSearchParam reportSearchParam) { + PqsDeviceUnit deviceUnit; + if (Objects.isNull(reportSearchParam.getResourceType())) { + deviceUnit = commTerminalGeneralClient.lineUnitDetail(reportSearchParam.getLineId()).getData(); + } else { + deviceUnit = csCommTerminalFeignClient.lineUnitDetail(reportSearchParam.getLineId()).getData(); + } + List dictData = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEVICE_UNIT.getCode()).getData(); + Map unit = new HashMap<>(); + List list = dictData.stream().map(DictData::getCode).collect(Collectors.toList()); + for (String s : list) { + //有效值 + if (s.equals(DicDataEnum.EFFECTIVE.getCode())) { + unit.put(s + "#i", deviceUnit.getIeffective()); + unit.put(s + "#v", deviceUnit.getLineVoltage()); + } + //功率 + if (s.equals(DicDataEnum.POWER.getCode())) { + unit.put(s + "#p", deviceUnit.getTotalActiveP()); + unit.put(s + "#q", deviceUnit.getTotalNoP()); + unit.put(s + "#s", deviceUnit.getTotalViewP()); + } + //畸变率 + if (s.equals(DicDataEnum.DISTORTION.getCode())) { + unit.put(s + "#v", deviceUnit.getVdistortion()); + } + //电压偏差 + if (s.equals(DicDataEnum.VOLTAGE.getCode())) { + unit.put(s + "#v", deviceUnit.getVoltageDev()); + } + //频率 + if (s.equals(DicDataEnum.UNIT_FREQUENCY.getCode())) { + unit.put(s + "#freq", deviceUnit.getUnitFrequency()); + unit.put(s + "#freqDev", deviceUnit.getUnitFrequencyDev()); + } + //三项不平衡度 + if (s.equals(DicDataEnum.UNBALANCE.getCode())) { + unit.put(s + "#v", STR_FOUR); + unit.put(s + "#vPos", deviceUnit.getPositiveV()); + unit.put(s + "#vNeg", deviceUnit.getNoPositiveV()); + unit.put(s + "#vZero", deviceUnit.getNoPositiveV()); + unit.put(s + "#i", STR_FOUR); + unit.put(s + "#iPos", "A"); + unit.put(s + "#iNeg", "A"); + unit.put(s + "#iZero", "A"); + } + //基波 + if (s.equals(DicDataEnum.FUND.getCode())) { + unit.put(s + "#i", deviceUnit.getIfund()); + unit.put(s + "#v", deviceUnit.getVfundEffective()); + + } + } + return unit; + } + + + /** + * 处理最终结果 + * @author cdf + * @date 2026/1/16 + */ + public void resultAssemble(List endList,ReportSearchParam reportSearchParam,List terminalList,JSONArray jsonArray){ + if (CollUtil.isNotEmpty(endList)) { + //数据单位信息 + Map unit = unitMap(reportSearchParam); + //进行反向赋值到模板 + //1、根据itemName分组 + Map> assMap = endList.stream().collect(Collectors.groupingBy(ReportTemplateDTO::getItemName)); + //处理台账信息 + Map finalTerminalMap; + if (CollUtil.isNotEmpty(terminalList)) { + finalTerminalMap = convertKeysToUpperCase(commTerminalGeneralClient.getCustomDetailByLineId(reportSearchParam.getLineId()).getData()); + }else { + finalTerminalMap = new HashMap<>(); + } + //2、把itemName的value赋给v和m + jsonArray.forEach(item -> { + JSONObject jsonObject = (JSONObject) item; + JSONArray itemArr = (JSONArray) jsonObject.get(CELL_DATA); + itemArr.forEach((it) -> { + if (Objects.nonNull(it) && !"null".equals(it.toString())) { + //获取到1列 + JSONObject data = (JSONObject) it; + JSONObject son = (JSONObject) data.get(V); + if (son.containsKey(V)) { + String v = son.getStr(V); + //数据格式:$HA[_25]#B#max#classId$ 或 $HA[_25]#max#classId$ + if (v.charAt(0) == '$' && v.contains(STR_ONE)) { + String str = ""; + List rDto = assMap.get(v.replace(STR_TWO, "").toUpperCase()); + if (Objects.nonNull(rDto)) { + str = rDto.get(0).getValue(); + //没有值,赋"/" + if (StringUtils.isBlank(str)) { + str = "/"; + } + son.set(V, str); + if (Objects.nonNull(rDto.get(0).getOverLimitFlag()) && rDto.get(0).getOverLimitFlag() == 1) { + son.set("fc", "#990000"); + } + } + } else if (v.charAt(0) == '%' && v.contains(STR_ONE)) { + //指标合格情况 + String str = ""; + List rDto = assMap.get(v.replace(STR_FOUR, "").toUpperCase()); + if (Objects.nonNull(rDto)) { + str = rDto.get(0).getValue(); + //没有值,赋"/" + if (StringUtils.isBlank(str)) { + str = "/"; + } + son.set(V, str); + if ("不合格".equals(str)) { + son.set("fc", "#990000"); + } + } + } else if (v.charAt(0) == '&') { + //结论 + String tem = v.replace(STR_THREE, "").toUpperCase(); + if (finalTerminalMap.size()>0) { + if ("STATIS_TIME".equals(tem)) { + //如何时间是大于当前时间则用当前时间 + String localTime = InfluxDbSqlConstant.END_TIME; + LocalDate localDate = LocalDateTimeUtil.parseDate(reportSearchParam.getEndTime(), DatePattern.NORM_DATE_PATTERN); + LocalDate nowDate = LocalDate.now(); + if (nowDate.isAfter(localDate)) { + son.set(V, reportSearchParam.getStartTime() + InfluxDbSqlConstant.START_TIME + "_" + reportSearchParam.getEndTime() + localTime); + } else { + localTime = " " + LocalTime.now().format(DatePattern.NORM_TIME_FORMATTER); + son.set(V, reportSearchParam.getStartTime() + InfluxDbSqlConstant.START_TIME + "_" + nowDate + localTime); + } + } else { + //台账信息 + son.set(V, finalTerminalMap.getOrDefault(tem, "/")); + } + } + } + //解决数据单位问题 @指标#类型@ + if (v.charAt(0) == '@' && v.contains(STR_ONE)) { + String replace = v.replace("@", ""); + son.set(V, unit.getOrDefault(replace, "/")); + + } + } + } + }); + }); + } + } + + /** + * map key转大写 + */ + public static Map convertKeysToUpperCase(Map originalMap) { + Map newMap = new HashMap<>(); + for (Map.Entry entry : originalMap.entrySet()) { + newMap.put(entry.getKey().toUpperCase(), entry.getValue()); + } + return newMap; + } + +} diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/MonitorCommReportServiceImpl.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/MonitorCommReportServiceImpl.java new file mode 100644 index 000000000..7de909629 --- /dev/null +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/MonitorCommReportServiceImpl.java @@ -0,0 +1,692 @@ +package com.njcn.harmonic.common.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.dynamic.datasource.annotation.DS; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.njcn.harmonic.pojo.param.ReportQueryParam; +import com.njcn.harmonic.pojo.po.RStatDataVD; +import com.njcn.harmonic.pojo.po.day.RStatDataHarmrateVDPO; +import com.njcn.harmonic.pojo.po.day.RStatDataIDPO; +import com.njcn.harmonic.pojo.po.day.RStatDataInharmVDPO; +import com.njcn.harmonic.pojo.vo.ReportValue; +import com.njcn.harmonic.common.mapper.*; +import com.njcn.harmonic.common.service.MonitorCommReportService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author wr + */ +@Service +@RequiredArgsConstructor +@DS("sjzx") +@Slf4j +public class MonitorCommReportServiceImpl implements MonitorCommReportService { + + private final MonitorCommReportMapper reportMapper; + private final RStatDataVDMapper statDataVDMapper; + private final RStatDataHarmRateVDMapper rStatDataHarmRateVDMapper; + private final RStatDataIDMapper rStatDataIDMapper; + private final RStatDataInharmVDMapper rStatDataInharmVDMapper; + + /* @Override + public OverLimitInfo getOverLimitData(ReportQueryParam param) { + + + OverLimitInfo overLimitInfo = new OverLimitInfo(); + + //查询时间段内共有多少条记录,并*0.95取整处理,用来计算CP95值 降序*0.05进一位计算 + double count = 0; + double pstCount = 0; + double pltCount = 0; + if (param.getB()) { + count = Math.ceil(1); + pltCount = Math.ceil(1); + pstCount = Math.ceil(1); + } else { + count = Math.ceil(reportMapper.getTotalCP95Day(param).intValue() * 0.05); + pltCount = Math.ceil(reportMapper.getTotalPltCP95Day(param).intValue() * 0.05); + pstCount = Math.ceil(reportMapper.getTotalPstCP95Day(param).intValue() * 0.05); + } + overLimitInfo.setCount(count); + overLimitInfo.setPltCount(pltCount); + overLimitInfo.setPstCount(pstCount); + return overLimitInfo; + } +*/ + @Override + public List getVirtualData(ReportQueryParam param) { + List list = new ArrayList<>(); + + // 获取电流有效值 + List listI = reportMapper.getVirtualDataI(param); + //获取电压有效值 + List listV = reportMapper.getVirtualDataV(param); + //获取线电压有效值 + List listVV = reportMapper.getVVirtualData(param); + + RegroupDataComm.regroupData(listV, true); + RegroupDataComm.regroupData(listI, true); + RegroupDataComm.regroupData(listVV, true); + list.addAll(listV); + list.addAll(listI); + list.addAll(listVV); + + return list; + } + + @Override + public List getPowerData(ReportQueryParam param) { + List list = new ArrayList<>(); + //获取有功功率 + List listP = reportMapper.getPowerP(param); + //获取无功功率 + List listQ = reportMapper.getPowerQ(param); + //获取视在功率 + List listS = reportMapper.getPowerS(param); + //获取功率因数 + List listF = reportMapper.getPF(param); + + RegroupDataComm.regroupData(listP, true, false); + RegroupDataComm.regroupData(listQ, true, false); + RegroupDataComm.regroupData(listS, true, false); + RegroupDataComm.regroupData(listF, true, false); + list.addAll(listP); + list.addAll(listQ); + list.addAll(listS); + list.addAll(listF); + return list; + } + + @Override + public List getFlickerData(ReportQueryParam param) { + List list = new ArrayList<>(); + + //短时闪变 + List listFlicker = reportMapper.getFlickerData(param); + //长时闪变 + List listLFlicker = reportMapper.getLFlickerData(param); + + RegroupDataComm.regroupData(listFlicker, true); + RegroupDataComm.regroupData(listLFlicker, true); + list.addAll(listFlicker); + list.addAll(listLFlicker); + + return list; + } + + @Override + public List getVdeviation(ReportQueryParam param) { + List list = new ArrayList<>(); + + //获取电压偏差 + List listU = reportMapper.getUVdeviationData(param); + List listL = reportMapper.getLVdeviationData(param); + + RegroupDataComm.regroupData(listU, true); + RegroupDataComm.regroupData(listL, true); + list.addAll(listU); + list.addAll(listL); + return list; + } + + @Override + public List getDistortionData(ReportQueryParam param) { + List list = new ArrayList<>(); + //获取电压畸变率 + List listU = reportMapper.getDistortionDataV(param); + //获取电流畸变率 + List listI = reportMapper.getDistortionDataI(param); + + //添加之前判断数据库是否有数据,如果没有数据模拟数据添加到集合中 + RegroupDataComm.regroupData(listU, true); + RegroupDataComm.regroupData(listI, true); + list.addAll(listU); + list.addAll(listI); + + return list; + } + + @Override + public List getFrequencyData(ReportQueryParam param) { + List list = new ArrayList<>(); + + List listFre = reportMapper.getFrequencyData(param); + List listFreDEV = reportMapper.getDEVFrequencyData(param); + + + RegroupDataComm.regroupData(listFre, true); + RegroupDataComm.regroupData(listFreDEV, true); + list.addAll(listFre); + list.addAll(listFreDEV); + return list; + } + + @Override + public List getThreephase(ReportQueryParam param) { + List list = new ArrayList<>(); + //电压三相不平衡度 + List listV = dataV(param, Arrays.asList("T"), 1, 5, true, 0); + //电流三相不平衡度 + List listI = dataI(param, Arrays.asList("T"), 1, 5, true, 0); + + if (CollUtil.isNotEmpty(listV)) { + list.addAll(listV); + } else { + regroupData(list); + } + + if (CollUtil.isNotEmpty(listI)) { + list.addAll(listI); + } else { + regroupData(list); + } + return list; + } + + @Override + public List getICurrent(ReportQueryParam param) { + List list = new ArrayList<>(); + + //获取电流幅值,包含基波 + List listI = dataI(param, Arrays.asList("A", "B", "C"), 1, 51, false, 0); + if (CollUtil.isEmpty(listI)) { + for (int i = 0; i < 50; i++) { + RegroupDataComm.regroupData(list, true, true); + } + } else { + list.addAll(listI); + } + return list; + } + + @Override + public List getVoltageRate(ReportQueryParam param) { + List list = new ArrayList<>(); + //这里获取的是电压有效值,不是V1 + //获取基波电压幅值,单位kV + List listV = dataV(param, Arrays.asList("A", "B", "C"), 1, 2, false, 5); + + if (CollUtil.isEmpty(listV)) { + RegroupDataComm.regroupData(list, true, true); + } else { + list.addAll(listV); + } + + //获取电压含有率,不包含基波 + List listRate = dataHarmV(param, Arrays.asList("A", "B", "C"), 2, 51, false, 1); + + if (CollUtil.isEmpty(listRate)) { + for (int i = 0; i < 49; i++) { + RegroupDataComm.regroupData(list, true, true); + } + } else { + list.addAll(listRate); + } + + //获取电压畸变率 + List listU = reportMapper.getDistortionDataV(param); + RegroupDataComm.regroupData(listU, true); + list.addAll(listU); + return list; + } + + @Override + public List getInharmVeRate(ReportQueryParam param) { + List inharm = rStatDataInharmVDMapper.selectList(new LambdaQueryWrapper() + .eq(RStatDataInharmVDPO::getLineId, param.getLineId()) + .in(RStatDataInharmVDPO::getPhaseType, Arrays.asList("A", "B", "C")) + .ge(StrUtil.isNotBlank(param.getStartTime()), RStatDataInharmVDPO::getTime, DateUtil.beginOfDay(DateUtil.parse(param.getStartTime()))) + .le(StrUtil.isNotBlank(param.getEndTime()), RStatDataInharmVDPO::getTime, DateUtil.endOfDay(DateUtil.parse(param.getEndTime()))) + ); + String max = "MAX"; + String avg = "AVG"; + String min = "MIN"; + String cp95 = "CP95"; + List a = new ArrayList<>(); + Map> collect = inharm.stream().collect(Collectors.groupingBy(RStatDataInharmVDPO::getPhaseType)); + collect.forEach((key, value) -> { + Map> valueTypeMap = value.stream().collect(Collectors.groupingBy(RStatDataInharmVDPO::getValueType)); + + for (int i = 1; i < 17; i++) { + ReportValue reportValue = new ReportValue(); + String attribute = "v" + i; + + if (valueTypeMap.containsKey(max)) { + List aa = reflectDataInV(valueTypeMap.get(max), max, attribute); + reportValue.setPhaseType(key); + Float maxNum = aa.stream().distinct().max(Float::compareTo).get(); + reportValue.setFmaxValue(maxNum); + } + if (valueTypeMap.containsKey(avg)) { + List aa = reflectDataInV(valueTypeMap.get(avg), avg, attribute); + reportValue.setPhaseType(key); + Double avgNum = aa.stream().distinct().collect(Collectors.averagingDouble(Float::doubleValue)); + reportValue.setMeanValue(avgNum.floatValue()); + } + if (valueTypeMap.containsKey(min)) { + List aa = reflectDataInV(valueTypeMap.get(min), min, attribute); + reportValue.setPhaseType(key); + double minNum = aa.stream().distinct().min(Float::compareTo).get(); + reportValue.setMinValue((float) minNum); + } + if (valueTypeMap.containsKey(cp95)) { + List aa = reflectDataInV(valueTypeMap.get(cp95), cp95, attribute); + reportValue.setPhaseType(key); + List cp95Num = aa.stream().distinct().sorted(Comparator.comparing(Float::doubleValue).reversed()).collect(Collectors.toList()); + reportValue.setCp95Value(cp95Num.get(0).floatValue()); + } + a.add(reportValue); + } + }); + if (CollUtil.isEmpty(a)) { + for (int i = 1; i < 17; i++) { + RegroupDataComm.regroupData(a, true, true); + } + } + return a; + } + + @Override + public List getINegDataRate(ReportQueryParam param) { + List list = new ArrayList<>(); + //负序电流 + List iNegData = reportMapper.getINegData(param); + RegroupDataComm.regroupData(iNegData, true); + list.addAll(iNegData); + return list; + } + + //赋值默认值 + private void regroupData(List list) { + for (int i = 0; i < 4; i++) { + List list1 = new ArrayList<>(); + RegroupDataComm.regroupData(list1, false); + list.addAll(list1); + } + } + + /** + * 电压信息 + * + * @param param 查询条件 + * @param valueTypes 区分类别 例如"A","B","C" + * @param num 循环开始 + * @param size 循环结束 + * @param fly 否是启用获取属性电压 + * @param index 获取属性位置名称 + * @return + */ + private List dataV(ReportQueryParam param, List valueTypes, Integer num, Integer size, Boolean fly, Integer index) { + List rStatDataVDS = statDataVDMapper.selectList(new LambdaQueryWrapper() + .eq(RStatDataVD::getLineId, param.getLineId()) + .in(CollUtil.isNotEmpty(valueTypes), RStatDataVD::getPhasicType, valueTypes) + .ge(StrUtil.isNotBlank(param.getStartTime()), RStatDataVD::getTime, DateUtil.beginOfDay(DateUtil.parse(param.getStartTime()))) + .le(StrUtil.isNotBlank(param.getEndTime()), RStatDataVD::getTime, DateUtil.endOfDay(DateUtil.parse(param.getEndTime()))) + ); + String max = "MAX"; + String avg = "AVG"; + String min = "MIN"; + String cp95 = "CP95"; + List a = new ArrayList<>(); + Map> collect = rStatDataVDS.stream().collect(Collectors.groupingBy(RStatDataVD::getPhasicType)); + collect.forEach((key, value) -> { + Map> valueTypeMap = value.stream().collect(Collectors.groupingBy(RStatDataVD::getValueType)); + + for (int i = num; i < size; i++) { + ReportValue reportValue = new ReportValue(); + String attribute = ""; + if (fly) { + if (index == 0) { + attribute = attributeV(i); + } else { + attribute = attributeV(index); + } + } else { + attribute = "v" + i; + } + + if (valueTypeMap.containsKey(max)) { + List aa = reflectDataV(valueTypeMap.get(max), max, attribute); + reportValue.setPhaseType(key); + Float maxNum = aa.stream().distinct().max(Float::compareTo).get(); + reportValue.setFmaxValue(maxNum); + } + if (valueTypeMap.containsKey(avg)) { + List aa = reflectDataV(valueTypeMap.get(avg), avg, attribute); + reportValue.setPhaseType(key); + Double avgNum = aa.stream().distinct().collect(Collectors.averagingDouble(Float::doubleValue)); + reportValue.setMeanValue(avgNum.floatValue()); + } + if (valueTypeMap.containsKey(min)) { + List aa = reflectDataV(valueTypeMap.get(min), min, attribute); + reportValue.setPhaseType(key); + double minNum = aa.stream().distinct().min(Float::compareTo).get(); + reportValue.setMinValue((float) minNum); + } + if (valueTypeMap.containsKey(cp95)) { + List aa = reflectDataV(valueTypeMap.get(cp95), cp95, attribute); + reportValue.setPhaseType(key); + List cp95Num = aa.stream().distinct().sorted(Comparator.comparing(Float::doubleValue).reversed()).collect(Collectors.toList()); + reportValue.setCp95Value(cp95Num.get(0).floatValue()); + } + a.add(reportValue); + } + }); + return a; + } + + /** + * 电压信息 + * + * @param param 查询条件 + * @param valueTypes 区分类别 例如"A","B","C" + * @param num 循环开始 + * @param size 循环结束 + * @param fly 否是启用获取属性电压 + * @param index 获取属性位置名称 + * @return + */ + private List dataHarmV(ReportQueryParam param, List valueTypes, Integer num, Integer size, Boolean fly, Integer index) { + List harmRateVDPOS = rStatDataHarmRateVDMapper.selectList(new LambdaQueryWrapper() + .eq(RStatDataHarmrateVDPO::getLineId, param.getLineId()) + .in(CollUtil.isNotEmpty(valueTypes), RStatDataHarmrateVDPO::getPhaseType, valueTypes) + .ge(StrUtil.isNotBlank(param.getStartTime()), RStatDataHarmrateVDPO::getTime, DateUtil.beginOfDay(DateUtil.parse(param.getStartTime()))) + .le(StrUtil.isNotBlank(param.getEndTime()), RStatDataHarmrateVDPO::getTime, DateUtil.endOfDay(DateUtil.parse(param.getEndTime()))) + ); + String max = "MAX"; + String avg = "AVG"; + String min = "MIN"; + String cp95 = "CP95"; + List a = new ArrayList<>(); + Map> collect = harmRateVDPOS.stream().collect(Collectors.groupingBy(RStatDataHarmrateVDPO::getPhaseType)); + //格式错误,之前数据50A,50B,50C,应该是50A,B,C + for (int i = num; i < size; i++) { + int finalI = i; + collect.forEach((key, value) -> { + Map> valueTypeMap = value.stream().collect(Collectors.groupingBy(RStatDataHarmrateVDPO::getValueType)); + + + ReportValue reportValue = new ReportValue(); + String attribute = ""; + if (fly) { + if (index == 0) { + attribute = attributeV(finalI); + } else { + attribute = attributeV(index); + } + } else { + attribute = "v" + finalI; + } + + if (valueTypeMap.containsKey(max)) { + List aa = reflectDataHarmV(valueTypeMap.get(max), max, attribute); + reportValue.setPhaseType(key); + Float maxNum = aa.stream().distinct().max(Float::compareTo).get(); + reportValue.setFmaxValue(maxNum); + } + if (valueTypeMap.containsKey(avg)) { + List aa = reflectDataHarmV(valueTypeMap.get(avg), avg, attribute); + reportValue.setPhaseType(key); + Double avgNum = aa.stream().distinct().collect(Collectors.averagingDouble(Float::doubleValue)); + reportValue.setMeanValue(avgNum.floatValue()); + } + if (valueTypeMap.containsKey(min)) { + List aa = reflectDataHarmV(valueTypeMap.get(min), min, attribute); + reportValue.setPhaseType(key); + double minNum = aa.stream().distinct().min(Float::compareTo).get(); + reportValue.setMinValue((float) minNum); + } + if (valueTypeMap.containsKey(cp95)) { + List aa = reflectDataHarmV(valueTypeMap.get(cp95), cp95, attribute); + reportValue.setPhaseType(key); + List cp95Num = aa.stream().distinct().sorted(Comparator.comparing(Float::doubleValue).reversed()).collect(Collectors.toList()); + reportValue.setCp95Value(cp95Num.get(0).floatValue()); + } + a.add(reportValue); + + }); + } + return a; + } + + /** + * 电压反射取属性值 + * + * @param value + * @param name + * @return + */ + private List reflectDataV(List value, String name, String attribute) { + Field field = null; + try { + field = RStatDataVD.class.getDeclaredField(attribute); + } catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } + field.setAccessible(true); + + Field finalField = field; + return value.stream().filter(x -> x.getValueType().equals(name)).map(temp -> { + BigDecimal o = null; + try { + o = (BigDecimal) finalField.get(temp); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + + return o.floatValue(); + }).collect(Collectors.toList()); + } + + private List reflectDataHarmV(List value, String name, String attribute) { + Field field = null; + try { + field = RStatDataHarmrateVDPO.class.getDeclaredField(attribute); + } catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } + field.setAccessible(true); + + Field finalField = field; + return value.stream().filter(x -> x.getValueType().equals(name)).map(temp -> { + Double o = null; + try { + o = (Double) finalField.get(temp); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + return o.floatValue(); + }).collect(Collectors.toList()); + } + + /** + * 电压反射取属性值 + * + * @param value + * @param name + * @return + */ + private List reflectDataInV(List value, String name, String attribute) { + Field field; + try { + field = RStatDataInharmVDPO.class.getDeclaredField(attribute); + } catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } + field.setAccessible(true); + + Field finalField = field; + return value.stream().filter(x -> x.getValueType().equals(name)).map(temp -> { + Double o; + try { + o = (Double) finalField.get(temp); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + + return o.floatValue(); + }).collect(Collectors.toList()); + } + + /** + * 电流信息 + * + * @param param + * @return + */ + private List dataI(ReportQueryParam param, List valueTypes, Integer num, Integer size, Boolean fly, Integer index) { + List rStatDataVDS = rStatDataIDMapper.selectList(new LambdaQueryWrapper() + .eq(RStatDataIDPO::getLineId, param.getLineId()) + .in(CollUtil.isNotEmpty(valueTypes), RStatDataIDPO::getPhaseType, valueTypes) + .ge(StrUtil.isNotBlank(param.getStartTime()), RStatDataIDPO::getTime, DateUtil.beginOfDay(DateUtil.parse(param.getStartTime()))) + .le(StrUtil.isNotBlank(param.getEndTime()), RStatDataIDPO::getTime, DateUtil.endOfDay(DateUtil.parse(param.getEndTime()))) + ); + String max = "MAX"; + String avg = "AVG"; + String min = "MIN"; + String cp95 = "CP95"; + List a = new ArrayList<>(); + Map> collect = rStatDataVDS.stream().collect(Collectors.groupingBy(RStatDataIDPO::getPhaseType)); + //格式错误,之前数据50A,50B,50C,应该是50A,B,C + for (int i = num; i < size; i++) { + int finalI = i; + collect.forEach((key, value) -> { + Map> valueTypeMap = value.stream().collect(Collectors.groupingBy(RStatDataIDPO::getValueType)); + + + ReportValue reportValue = new ReportValue(); + String attribute = ""; + if (fly) { + if (index == 0) { + attribute = attributeI(finalI); + } else { + attribute = attributeI(index); + } + } else { + attribute = "i" + finalI; + } + if (valueTypeMap.containsKey(max)) { + List aa = reflectDataI(valueTypeMap.get(max), max, attribute); + reportValue.setPhaseType(key); + Float maxNum = aa.stream().distinct().max(Float::compareTo).get(); + reportValue.setFmaxValue(maxNum); + } + if (valueTypeMap.containsKey(avg)) { + List aa = reflectDataI(valueTypeMap.get(avg), avg, attribute); + reportValue.setPhaseType(key); + Double avgNum = aa.stream().distinct().collect(Collectors.averagingDouble(Float::doubleValue)); + reportValue.setMeanValue(avgNum.floatValue()); + } + if (valueTypeMap.containsKey(min)) { + List aa = reflectDataI(valueTypeMap.get(min), min, attribute); + reportValue.setPhaseType(key); + double minNum = aa.stream().distinct().min(Float::compareTo).get(); + reportValue.setMinValue((float) minNum); + } + if (valueTypeMap.containsKey(cp95)) { + List aa = reflectDataI(valueTypeMap.get(cp95), cp95, attribute); + reportValue.setPhaseType(key); + List cp95Num = aa.stream().distinct().sorted(Comparator.comparing(Float::doubleValue).reversed()).collect(Collectors.toList()); + reportValue.setCp95Value(cp95Num.get(0).floatValue()); + } + a.add(reportValue); + + }); + } + return a; + } + + /** + * 电流反射取属性值 + * + * @param value + * @param name + * @return + */ + private List reflectDataI(List value, String name, String attribute) { + Field field = null; + try { + field = RStatDataIDPO.class.getDeclaredField(attribute); + } catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } + field.setAccessible(true); + Field finalField = field; + return value.stream().filter(x -> x.getValueType().equals(name)).map(temp -> { + Double o = null; + try { + o = (Double) finalField.get(temp); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + + return o.floatValue(); + }).collect(Collectors.toList()); + } + + /** + * 获取属性电压 + * + * @param i + * @return + */ + private String attributeV(Integer i) { + String str = null; + switch (i) { + case 1: + str = "vUnbalance"; + break; + case 2: + str = "vPos"; + break; + case 3: + str = "vNeg"; + break; + case 4: + str = "vZero"; + break; + case 5: + str = "v1"; + break; + default: + break; + } + return str; + } + + /** + * 获取属性电流 + * + * @param i + * @return + */ + private String attributeI(Integer i) { + String str = null; + switch (i) { + case 1: + str = "iUnbalance"; + break; + case 2: + str = "iPos"; + break; + case 3: + str = "iNeg"; + break; + case 4: + str = "iZero"; + break; + default: + break; + } + return str; + } +} diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/MonitorHarmonicReportServiceImpl.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/MonitorHarmonicReportServiceImpl.java new file mode 100644 index 000000000..796379621 --- /dev/null +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/MonitorHarmonicReportServiceImpl.java @@ -0,0 +1,1830 @@ +package com.njcn.harmonic.common.service.impl; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.dynamic.datasource.annotation.DS; +import com.njcn.common.pojo.enums.response.CommonResponseEnum; +import com.njcn.common.pojo.exception.BusinessException; +import com.njcn.common.utils.PubUtils; +import com.njcn.device.biz.pojo.po.PqsDeviceUnit; +import com.njcn.device.pms.api.MonitorClient; +import com.njcn.device.pms.pojo.po.Monitor; +import com.njcn.device.pq.api.DeviceUnitClient; +import com.njcn.harmonic.common.pojo.dto.DeviceUnitCommDTO; +import com.njcn.harmonic.pojo.param.ReportQueryParam; +import com.njcn.harmonic.pojo.po.report.EnumPass; +import com.njcn.harmonic.pojo.po.report.Pass; +import com.njcn.harmonic.pojo.po.report.ReportTarget; +import com.njcn.harmonic.pojo.vo.ReportValue; +import com.njcn.harmonic.common.pojo.dto.LineDetailDataCommVO; +import com.njcn.harmonic.common.pojo.dto.OverLimitInfoCommDTO; +import com.njcn.harmonic.common.service.MonitorCommReportService; +import com.njcn.harmonic.common.service.MonitorHarmonicReportService; +import com.njcn.harmonic.utils.WordUtil2; +import com.njcn.system.api.DicDataFeignClient; +import com.njcn.system.api.ThemeFeignClient; +import com.njcn.system.enums.DicDataEnum; +import com.njcn.system.enums.DicDataTypeEnum; +import com.njcn.system.pojo.po.DictData; +import com.njcn.system.pojo.po.Theme; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import sun.misc.BASE64Encoder; + +import javax.imageio.ImageIO; +import javax.servlet.http.HttpServletResponse; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +/** + * pqs + * + * @author cdf + * @date 2026/1/17 + */ +@Service +@Slf4j +@RequiredArgsConstructor +@DS("sjzx") +public class MonitorHarmonicReportServiceImpl implements MonitorHarmonicReportService { + + + /** + * 非谐波数据 + */ + List listVirtual; + List listPower; + List listFlicker; + List listDistortion; + List listVdeviation; + List listFrequency; + List listThreephase; + /** + * 谐波电压数据 + */ + List listVoltageRate; + /** + * 谐波电流数据 + */ + List listICurrent; + + + private final MonitorClient monitorClient; + private final DicDataFeignClient dicDataFeignClient; + private final ThemeFeignClient themeFeignClient; + private final MonitorCommReportService reportService; + private final DeviceUnitClient deviceUnitClient; + private final WordUtil2 wordUtil2; + + /** + * @param response + * @param startTime 开始时间 + * @param endTime 结束时间 + * @param type 区分pq:0 pms:1 + * @param lineIndex 监测点id + * @param name 监测点名称 + * @param reportNumber 客户编号 + * @param crmName 客户名称 + * @param file 接线图 + * @param isUrl 是否地址栏返回 + * @return + * @throws IOException + */ + @Override + public void exportWorld(HttpServletResponse response, + String startTime, + String endTime, + Integer type, + String lineIndex, + String name, + String reportNumber, + String crmName, + Boolean isUrl, + MultipartFile file, + LineDetailDataCommVO lineDto, OverLimitInfoCommDTO overLimit, DeviceUnitCommDTO deviceUnit) { + //获取监测点信息 + String bdname; + Integer pttype; + String areaName; + String atype = ""; + String btype = ""; + String ctype = ""; + if (type == 0) { + if (ObjectUtil.isNull(lineDto)) { + throw new BusinessException(CommonResponseEnum.NO_DATA); + } + bdname = lineDto.getBdName(); + areaName = lineDto.getAreaName(); + if("冀北".equals(areaName)){ + areaName="国网"+areaName; + } + pttype = PubUtils.ptTypeName(lineDto.getPtType()); + } else { + List monitorList = monitorClient.getMonitorList(Collections.singletonList(lineIndex)).getData(); + if (ObjectUtil.isNull(monitorList)) { + throw new BusinessException(CommonResponseEnum.NO_DATA); + } + Monitor monitor = monitorList.get(0); + bdname = monitor.getPowerrName(); + areaName = monitor.getOrgName(); + String terminalWiringMethod = dicDataFeignClient.getDicDataById(monitor.getTerminalWiringMethod()).getData().getName(); + pttype = PubUtils.ptTypeName(terminalWiringMethod); + lineDto.setPt(monitor.getPt1() + "/" + monitor.getPt2()); + lineDto.setCt(monitor.getCt1() + "/" + monitor.getCt2()); + //基准容量 + lineDto.setStandardCapacity(monitor.getStandShortCapacity()); + //短路容量 + lineDto.setShortCapacity(monitor.getMinShortCircuitCapacity()); + //协议容量 + lineDto.setDealCapacity(monitor.getUserAgreementCapacity()); + //设备容量 + lineDto.setDevCapacity(monitor.getPowerSupplyEqCapacity()); + //电压等级 + lineDto.setScale(dicDataFeignClient.getDicDataById(monitor.getVoltageLevel()).getData().getName()); + + } + if (pttype == 0) { + atype = "A相"; + btype = "B相"; + ctype = "C相"; + } else if (pttype == 1) { + atype = "AB相"; + btype = "BC相"; + ctype = "CA相"; + } else if (pttype == 2) { + atype = "AB相"; + btype = "BC相"; + ctype = "-"; + + } + DateTime startDate = DateUtil.beginOfDay(DateUtil.parse(startTime)); + DateTime endDate = DateUtil.endOfDay(DateUtil.parse(endTime)); + long day = DateUtil.betweenDay(startDate, endDate, false); + //通用查询条件 + ReportQueryParam param = new ReportQueryParam(); + param.setLineId(lineIndex); + param.setStartTime(DateUtil.format(startDate, "yyyy-MM-dd HH:mm:ss")); + LocalDateTime parse = LocalDateTimeUtil.parse(DateUtil.format(endDate, "yyyy-MM-dd HH:mm:ss"), DatePattern.NORM_DATETIME_PATTERN); + if(LocalDateTime.now().isBefore(parse)){ + param.setEndTime(LocalDateTimeUtil.format(LocalDateTime.now(),DatePattern.NORM_DATETIME_PATTERN)); + endDate = DateUtil.parse(LocalDateTimeUtil.format(LocalDateTime.now(),DatePattern.NORM_DATETIME_PATTERN)); + + }else { + param.setEndTime(DateUtil.format(endDate, "yyyy-MM-dd HH:mm:ss")); + } + param.setB(day == 0); + + + if (Objects.isNull(overLimit)) { + throw new BusinessException(CommonResponseEnum.FAIL,"限值获取为空"); + } + + String rtfPath; + String picPath = "file/default.jpg"; + + Theme theme = themeFeignClient.getTheme().getData(); + if (theme.getRemark().equals("国网")) { + rtfPath = "file/reportModelGW.docx"; + } else if (theme.getRemark().equals("南网")) { + rtfPath = "file/reportModelNW.docx"; + } else if (theme.getRemark().equals("灿能")) { + rtfPath = "file/reportModelCN.docx"; + } else if (theme.getName().contains("物联")) { + rtfPath = "file/reportModelWL.docx"; + } else { + rtfPath = "file/reportModel.docx"; + } + + //获取图片信息 + ClassPathResource picPathResource = null; + try { + picPathResource = new ClassPathResource(picPath); + rtfPath = rtfPath.replaceAll("%20", " "); + } catch (Exception e1) { + log.info("获取报表发生异常,异常是" + e1.getMessage()); + } + //上移提前塞入基波电压基波电流 + getCurrentRate(param, overLimit); + getVoltageRate(param, overLimit); + + // 报告Map + Map reportmap = new HashMap<>(16); + + reportmap.putAll(unitMap(deviceUnit)); + reportmap.put("$atype$", atype); + reportmap.put("$btype$", btype); + reportmap.put("$ctype$", ctype); + + + // ======== 修复后的图片处理核心逻辑 ======== + Map header = handleImageData(file, picPathResource); + reportmap.put("$image$", header); + reportmap.put("$image$", header); + + getVirtualData(param); + // 电压幅值 + ReportValue voltage1 = this.listVirtual.get(0).getList().get(0); + // 电压幅值 + ReportValue voltage2 = this.listVirtual.get(0).getList().get(1); + // 电压幅值 + ReportValue voltage3 = this.listVirtual.get(0).getList().get(2); + // 电流幅值 + ReportValue current1 = this.listVirtual.get(1).getList().get(0); + // 电流幅值 + ReportValue current2 = this.listVirtual.get(1).getList().get(1); + // 电流幅值 + ReportValue current3 = this.listVirtual.get(1).getList().get(2); + + String strLineBaseName = String.format("%s%s", new String[]{bdname + "_", name}); + // 分析建议 + String strAnalysis = ""; + // 报表错误 + String strError = ""; + + /************************************************************** + **** 基波电压/电流有效值表格 + * 一、用基波电压和基波电流做是否有值的判断, 判断策略为所有的基波电压和基波电流都为空 + * ************************************* + * ************************************* 二、基本数据判断 + * ①、(最大值>=最小值、平均值、95%概率值) ②、(平均值>=最小值) ③、(95%概率值>=最小值) + ***************************************************************/ + String strBaseVIResult = ""; + // 基波电压最大值 + + reportmap.put("$B" + "V0" + "X" + "_A$", judgeNull(voltage1.getFmaxValue())); + + reportmap.put("$B" + "V0" + "X" + "_B$", judgeNull(voltage2.getFmaxValue())); + reportmap.put("$B" + "V0" + "X" + "_C$", judgeNull(voltage3.getFmaxValue())); + + // 基波电流最大值 + reportmap.put("$B" + "I0" + "X" + "_A$", judgeNull(current1.getFmaxValue())); + reportmap.put("$B" + "I0" + "X" + "_B$", judgeNull(current2.getFmaxValue())); + reportmap.put("$B" + "I0" + "X" + "_C$", judgeNull(current3.getFmaxValue())); + + /************************************************************** + **** 三张大表基础数据幅值 + ***************************************************************/ + // 基波电压最大值 + reportmap.put("$C" + "V0" + "X" + "_A$", judgeNull(this.listVoltageRate.get(0).getList().get(0).getFmaxValue())); + reportmap.put("$C" + "V0" + "X" + "_B$", judgeNull(this.listVoltageRate.get(0).getList().get(1).getFmaxValue())); + reportmap.put("$C" + "V0" + "X" + "_C$", judgeNull(this.listVoltageRate.get(0).getList().get(2).getFmaxValue())); + + // 基波电流最大值 + reportmap.put("$C" + "I0" + "X" + "_A$", judgeNull(this.listICurrent.get(0).getList().get(0).getFmaxValue())); + reportmap.put("$C" + "I0" + "X" + "_B$", judgeNull(this.listICurrent.get(0).getList().get(1).getFmaxValue())); + reportmap.put("$C" + "I0" + "X" + "_C$", judgeNull(this.listICurrent.get(0).getList().get(2).getFmaxValue())); + + // 基波电压最小值 + reportmap.put("$B" + "V0" + "N" + "_A$", judgeNull(voltage1.getMinValue())); + reportmap.put("$B" + "V0" + "N" + "_B$", judgeNull(voltage2.getMinValue())); + reportmap.put("$B" + "V0" + "N" + "_C$", judgeNull(voltage3.getMinValue())); + + // 基波电流最小值 + reportmap.put("$B" + "I0" + "N" + "_A$", judgeNull(current1.getMinValue())); + reportmap.put("$B" + "I0" + "N" + "_B$", judgeNull(current2.getMinValue())); + reportmap.put("$B" + "I0" + "N" + "_C$", judgeNull(current3.getMinValue())); + + /************************************************************** + **** 三张大表基础数据幅值 + ***************************************************************/ + // 基波电压最小值 + reportmap.put("$C" + "V0" + "N" + "_A$", judgeNull(this.listVoltageRate.get(0).getList().get(0).getMinValue())); + reportmap.put("$C" + "V0" + "N" + "_B$", judgeNull(this.listVoltageRate.get(0).getList().get(1).getMinValue())); + reportmap.put("$C" + "V0" + "N" + "_C$", judgeNull(this.listVoltageRate.get(0).getList().get(2).getMinValue())); + + // 基波电流最小值 + reportmap.put("$C" + "I0" + "N" + "_A$", judgeNull(this.listICurrent.get(0).getList().get(0).getMinValue())); + reportmap.put("$C" + "I0" + "N" + "_B$", judgeNull(this.listICurrent.get(0).getList().get(1).getMinValue())); + reportmap.put("$C" + "I0" + "N" + "_C$", judgeNull(this.listICurrent.get(0).getList().get(2).getMinValue())); + + // 基波电压平均值 + reportmap.put("$B" + "V0" + "E" + "_A$", judgeNull(voltage1.getMeanValue())); + reportmap.put("$B" + "V0" + "E" + "_B$", judgeNull(voltage2.getMeanValue())); + reportmap.put("$B" + "V0" + "E" + "_C$", judgeNull(voltage3.getMeanValue())); + + // 基波电流平均值 + reportmap.put("$B" + "I0" + "E" + "_A$", judgeNull(current1.getMeanValue())); + reportmap.put("$B" + "I0" + "E" + "_B$", judgeNull(current2.getMeanValue())); + reportmap.put("$B" + "I0" + "E" + "_C$", judgeNull(current3.getMeanValue())); + + /************************************************************** + **** 三张大表基础数据幅值 + ***************************************************************/ + // 基波电压平均值 + reportmap.put("$C" + "V0" + "E" + "_A$", judgeNull(this.listVoltageRate.get(0).getList().get(0).getMeanValue())); + reportmap.put("$C" + "V0" + "E" + "_B$", judgeNull(this.listVoltageRate.get(0).getList().get(1).getMeanValue())); + reportmap.put("$C" + "V0" + "E" + "_C$", judgeNull(this.listVoltageRate.get(0).getList().get(2).getMeanValue())); + + // 基波电流平均值 + reportmap.put("$C" + "I0" + "E" + "_A$", judgeNull(this.listICurrent.get(0).getList().get(0).getMeanValue())); + reportmap.put("$C" + "I0" + "E" + "_B$", judgeNull(this.listICurrent.get(0).getList().get(1).getMeanValue())); + reportmap.put("$C" + "I0" + "E" + "_C$", judgeNull(this.listICurrent.get(0).getList().get(2).getMeanValue())); + + // 基波电压cp95值 + reportmap.put("$B" + "V0" + "%" + "_A$", judgeNull(voltage1.getCp95Value())); + reportmap.put("$B" + "V0" + "%" + "_B$", judgeNull(voltage2.getCp95Value())); + reportmap.put("$B" + "V0" + "%" + "_C$", judgeNull(voltage3.getCp95Value())); + + // 基波电流cp95值 + reportmap.put("$B" + "I0" + "%" + "_A$", judgeNull(current1.getCp95Value())); + reportmap.put("$B" + "I0" + "%" + "_B$", judgeNull(current2.getCp95Value())); + reportmap.put("$B" + "I0" + "%" + "_C$", judgeNull(current3.getCp95Value())); + + /************************************************************** + **** 三张大表基础数据幅值 + ***************************************************************/ + // 基波电压cp95值 + reportmap.put("$C" + "V0" + "%" + "_A$", judgeNull(this.listVoltageRate.get(0).getList().get(0).getCp95Value())); + reportmap.put("$C" + "V0" + "%" + "_B$", judgeNull(this.listVoltageRate.get(0).getList().get(1).getCp95Value())); + reportmap.put("$C" + "V0" + "%" + "_C$", judgeNull(this.listVoltageRate.get(0).getList().get(2).getCp95Value())); + + // 基波电流cp95值 + reportmap.put("$C" + "I0" + "%" + "_A$", judgeNull(this.listICurrent.get(0).getList().get(0).getCp95Value())); + reportmap.put("$C" + "I0" + "%" + "_B$", judgeNull(this.listICurrent.get(0).getList().get(1).getCp95Value())); + reportmap.put("$C" + "I0" + "%" + "_C$", judgeNull(this.listICurrent.get(0).getList().get(2).getCp95Value())); + + // 遍历map中的值 + int iCount = 0; + // 判断所取的基波电压、基波电流值是否为null + for (Object value : reportmap.values()) { + if (value == null) + iCount++; + } + // 假如所有的数据都为null,则返回(所选的时间段内未找到数据) + if (iCount == reportmap.size()) { + throw new BusinessException(CommonResponseEnum.FAIL,"范围时间段为空"); + + } + // 基本数据判断 + for (int i = 0; i < 3; i++) { + String tmpstrMap = "A"; + switch (i) { + case 0: + tmpstrMap = "A"; + break; + case 1: + tmpstrMap = "B"; + break; + default: + tmpstrMap = "C"; + break; + } + try { + // 基波电压 + Double vmaxValue = Double.parseDouble(reportmap.get("$BV0X_" + tmpstrMap + "$").toString()); + Double vminValue = Double.parseDouble(reportmap.get("$BV0N_" + tmpstrMap + "$").toString()); + Double vaveValue = Double.parseDouble(reportmap.get("$BV0E_" + tmpstrMap + "$").toString()); + Double vcp95Value = Double.parseDouble(reportmap.get("$BV0%_" + tmpstrMap + "$").toString()); + // 基波电流 + Double imaxValue = Double.parseDouble(reportmap.get("$BI0X_" + tmpstrMap + "$").toString()); + Double iminValue = Double.parseDouble(reportmap.get("$BI0N_" + tmpstrMap + "$").toString()); + Double iaveValue = Double.parseDouble(reportmap.get("$BI0E_" + tmpstrMap + "$").toString()); + Double icp95Value = Double.parseDouble(reportmap.get("$BI0%_" + tmpstrMap + "$").toString()); + + if (!(vmaxValue >= vminValue && vmaxValue >= vaveValue && vmaxValue >= vcp95Value)) { + strBaseVIResult += "注意:从上表中可以看出" + strLineBaseName + + "基波电压/电流数据存在异常( 1、最大值>=最小值、平均值、95%概率值;2、平均值>=最小值;3、95%概率值>=最小值)。\r\n"; + break; + } else if (vaveValue < vminValue) { + strBaseVIResult += "注意:从上表中可以看出" + strLineBaseName + + "基波电压/电流数据存在异常( 1、最大值>=最小值、平均值、95%概率值;2、平均值>=最小值;3、95%概率值>=最小值)。\r\n"; + break; + } else if (vcp95Value < vminValue) { + strBaseVIResult += "注意:从上表中可以看出" + strLineBaseName + + "基波电压/电流数据存在异常( 1、最大值>=最小值、平均值、95%概率值;2、平均值>=最小值;3、95%概率值>=最小值)。\r\n"; + break; + } else if (!(imaxValue >= iminValue && imaxValue >= iaveValue && imaxValue >= icp95Value)) { + strBaseVIResult += "注意:从上表中可以看出" + strLineBaseName + + "基波电压/电流数据存在异常( 1、最大值>=最小值、平均值、95%概率值;2、平均值>=最小值;3、95%概率值>=最小值)。\r\n"; + break; + } else if (iaveValue < iminValue) { + strBaseVIResult += "注意:从上表中可以看出" + strLineBaseName + + "基波电压/电流数据存在异常( 1、最大值>=最小值、平均值、95%概率值;2、平均值>=最小值;3、95%概率值>=最小值)。\r\n"; + break; + } else if (icp95Value < iminValue) { + strBaseVIResult += "注意:从上表中可以看出" + strLineBaseName + + "基波电压/电流数据存在异常( 1、最大值>=最小值、平均值、95%概率值;2、平均值>=最小值;3、95%概率值>=最小值)。\r\n"; + break; + } + } catch (Exception e) { + strBaseVIResult += "注意:从上表中可以看出" + strLineBaseName + "基波电压/电流数据存在异常(不是数值类型)。\r\n"; + break; + } + } + reportmap.put("$BaseVIResult$", strBaseVIResult); + if (!"".equals(strBaseVIResult)) + strError += strBaseVIResult; + + /************************************************************** + **** 所选的时间段内有数据存在则进行其他加载 + ***************************************************************/ + +// Depts dep = R.getCurrentDept(); +// String detpName = dep.getArea(); + // 区域名称 + reportmap.put("$detpName$", areaName); + // 获取报告生成时间 + Date currentTime = new Date(); + // 报告日期格式 + SimpleDateFormat dayFormatter = new SimpleDateFormat("yyyy年MM月dd日"); + // 报告时分秒格式 + SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒"); + String strTime = String.format("%s——%s。", + new String[]{DateUtil.format(startDate, "yyyy年MM月dd日 HH时mm分ss秒"), + DateUtil.format(endDate, "yyyy年MM月dd日 HH时mm分ss秒")}); + // 报告编号 + if(StrUtil.isNotBlank(reportNumber)){ + reportmap.put("$number$", reportNumber); + }else { + reportmap.put("$number$", ""); + } + + // 客户名称 + reportmap.put("$titlePoint$", crmName); + // 报告生成时间 + reportmap.put("$TitleTime$", dayFormatter.format(currentTime)); + // 报告标题 + reportmap.put("$ReportTitle$", + String.format("对该地区%s电能质量在线监测数据进行分析, 以判断电能质量指标是否满足国标。", new String[]{strLineBaseName})); + // 报告分析时间段 + reportmap.put("$ReportTime$", strTime); + // 运行数据分析 + reportmap.put("$RunBaseName$", String.format("以下将对%s电能质量统计数据进行分析,数据包括基波电压/电流、谐波电压/电流、电压偏差、三相电压不平衡度、电压闪变、频率偏差。", + new String[]{strLineBaseName})); + // 基波电压和电流 + reportmap.put("$BaseVITable$", String.format("报告分析时间段内%s的基波电压/电流分钟统计数据见下表。", new String[]{strLineBaseName})); + // 供电电压偏差 + reportmap.put("$VDTable$", String.format("报告分析时间段内%s的电压偏差统计数据见下表。", new String[]{strLineBaseName})); + // 频率偏差 + reportmap.put("$FRETable$", String.format("报告分析时间段内%s的频率偏差统计数据见下表。", new String[]{strLineBaseName})); + // 三相电压不平衡度 + reportmap.put("$THETable$", String.format("报告分析时间段内%s的三相电压不平衡度统计数据见下表。", new String[]{strLineBaseName})); + // 闪变 + reportmap.put("$PLTTable$", String.format("报告分析时间段内%s的闪变统计数据见下表。", new String[]{strLineBaseName})); + // 谐波电压 + reportmap.put("$RVTable$", + String.format("报告分析时间段内%s的2-25次谐波电压含有率CP95概率值统计数据见下表。", new String[]{strLineBaseName})); + // 谐波电流 + reportmap.put("$RITable$", + String.format("报告分析时间段内%s的2-25次谐波电流幅值CP95概率值统计数据见下表。", new String[]{strLineBaseName})); + // 监测点名称1 + reportmap.put("$LineName1$", name); + // 监测点名称2 + reportmap.put("$LineName2$", name); + // 监测点名称3 + reportmap.put("$LineName3$", name); + // 监测点名称4 + reportmap.put("$LineName4$", name); + // 监测点名称5 + reportmap.put("$LineName5$", name); + + /********************** + **** 数据获取 + ***********************/ + + getPowerData(param); + getFlicker(param, overLimit); + getVdeviation(param, overLimit); + getDistortion(param, overLimit); + getFre(param, overLimit); + getThreePhase(param, overLimit); +// getVoltageRate(param, overLimit); +// getCurrentRate(param, overLimit); + // 短闪 + ReportValue pst1 = this.listFlicker.get(0).getList().get(0); + // 短闪 + ReportValue pst2 = this.listFlicker.get(0).getList().get(1); + // 短闪 + ReportValue pst3 = this.listFlicker.get(0).getList().get(2); + // 长闪 + ReportValue plt1 = this.listFlicker.get(1).getList().get(0); + // 长闪 + ReportValue plt2 = this.listFlicker.get(1).getList().get(1); + // 长闪 + ReportValue plt3 = this.listFlicker.get(1).getList().get(2); + // 监测点基本信息 + reportmap.put("$LineBase$", String.format("%s%s,CT变比为:%s,PT变比为:%s。", + new String[]{bdname, name, lineDto.getCt(), lineDto.getPt()})); + + /************************************************************** + **** 三张大表基础数据幅值 + ***************************************************************/ + reportmap.put("$CI_JCD$", bdname); + reportmap.put("$bdTitle$", bdname); + + reportmap.put("$CI_Time$", strTime); + reportmap.put("$CI_JCXL$", name); + reportmap.put("$CI_PT$", lineDto.getPt()); + reportmap.put("$CI_DYDJ$", lineDto.getScale()); + reportmap.put("$CI_CT$", lineDto.getCt()); + reportmap.put("$CI_JZRL$", String.valueOf(lineDto.getStandardCapacity())); + reportmap.put("$CI_DLRL$", String.valueOf(lineDto.getShortCapacity())); + reportmap.put("$CI_XYRL$", String.valueOf(lineDto.getDealCapacity())); + reportmap.put("$CI_SBRL$", String.valueOf(lineDto.getDevCapacity())); + + reportmap.put("$CV_JCD$", bdname); + reportmap.put("$CV_Time$", strTime); + reportmap.put("$CV_JCXL$", name); + reportmap.put("$CV_PT$", lineDto.getPt()); + reportmap.put("$CV_DYDJ$", lineDto.getScale()); + reportmap.put("$CV_CT$", lineDto.getCt()); + reportmap.put("$CV_JZRL$", String.valueOf(lineDto.getStandardCapacity())); + reportmap.put("$CV_DLRL$", String.valueOf(lineDto.getShortCapacity())); + reportmap.put("$CV_XYRL$", String.valueOf(lineDto.getDealCapacity())); + reportmap.put("$CV_SBRL$", String.valueOf(lineDto.getDevCapacity())); + + reportmap.put("$FV_JCD$", bdname); + reportmap.put("$FV_Time$", strTime); + reportmap.put("$FV_JCXL$", name); + reportmap.put("$FV_PT$", lineDto.getPt()); + reportmap.put("$FV_DYDJ$", lineDto.getScale()); + reportmap.put("$FV_CT$", lineDto.getCt()); + reportmap.put("$FV_JZRL$", String.valueOf(lineDto.getStandardCapacity())); + reportmap.put("$FV_DLRL$", String.valueOf(lineDto.getShortCapacity())); + reportmap.put("$FV_XYRL$", String.valueOf(lineDto.getDealCapacity())); + reportmap.put("$FV_SBRL$", String.valueOf(lineDto.getDevCapacity())); + + Double maxValue = 0.00; + Double minValue = 0.00; + Double aveValue = 0.00; + Double cp95Value = 0.00; + Double cp95ValueA = 0.00; + Double cp95ValueB = 0.00; + Double cp95ValueC = 0.00; + Double limit = 0.00; + /************************************************************** + **** 电压偏差(上偏差和下偏差) + ***************************************************************/ + ReportValue vdeviation1 = this.listVdeviation.get(0).getList().get(0); + ReportValue vdeviation2 = this.listVdeviation.get(0).getList().get(1); + ReportValue vdeviation3 = this.listVdeviation.get(0).getList().get(2); + // 获取电压上下偏差的国标限值 + String vdeviationLimit = judgeNull(this.listVdeviation.get(0).getOverLimit()); + //电压下偏差 + String ldeviationLimit = judgeNull(this.listVdeviation.get(1).getOverLimit()); + + reportmap.put("$VD_L$",ldeviationLimit+"至"+ vdeviationLimit); + String strResultVdeviationdata = ""; + String tmpstrResultVdeviationdata = ""; + String strResultVdeviationdataValue = ""; + String tmpstrMap = ""; + + // 获取电压偏差 + // 值错误判断 + try { + for (int i = 0; i < 3; i++) { + switch (i) { + case 0: + tmpstrMap = "A"; + break; + case 1: + tmpstrMap = "B"; + break; + default: + tmpstrMap = "C"; + break; + } + ReportValue vdeviation = this.listVdeviation.get(0).getList().get(i); + if(Objects.equals("C",tmpstrMap)&&pttype == 2){ + reportmap.put("$VDTX_C$", "-"); + reportmap.put("$VDTN_C$", "-"); + reportmap.put("$VDTE_C$", "-"); + reportmap.put("$VDT%_C$", "-"); + continue; + }else { + reportmap.put("$VDTX_" + tmpstrMap + "$", judgeNull(vdeviation.getFmaxValue())); + reportmap.put("$VDTN_" + tmpstrMap + "$", judgeNull(vdeviation.getMinValue())); + reportmap.put("$VDTE_" + tmpstrMap + "$", judgeNull(vdeviation.getMeanValue())); + reportmap.put("$VDT%_" + tmpstrMap + "$", judgeNull(vdeviation.getCp95Value())); + } + + + // 电压偏差 + Double vmaxValue = Double.parseDouble(reportmap.get("$VDTX_" + tmpstrMap + "$").toString()); + Double vminValue = Double.parseDouble(reportmap.get("$VDTN_" + tmpstrMap + "$").toString()); + Double vaveValue = Double.parseDouble(reportmap.get("$VDTE_" + tmpstrMap + "$").toString()); + Double vcp95Value = Double.parseDouble(reportmap.get("$VDT%_" + tmpstrMap + "$").toString()); + + if("".equals(strResultVdeviationdataValue)){ + if (!(vmaxValue >= vminValue && vmaxValue >= vaveValue && vmaxValue >= vcp95Value)) { + strResultVdeviationdataValue += "注意:从上表中可以看出" + strLineBaseName + + "电压偏差数据存在异常( 1、最大值>=最小值、平均值、95%概率值;2、平均值>=最小值;3、95%概率值>=最小值)。\r\n"; + } else if (vaveValue < vminValue) { + strResultVdeviationdataValue += "注意:从上表中可以看出" + strLineBaseName + + "电压偏差数据存在异常( 1、最大值>=最小值、平均值、95%概率值;2、平均值>=最小值;3、95%概率值>=最小值)。\r\n"; + } else if (vcp95Value < vminValue) { + strResultVdeviationdataValue += "注意:从上表中可以看出" + strLineBaseName + + "电压偏差数据数据存在异常( 1、最大值>=最小值、平均值、95%概率值;2、平均值>=最小值;3、95%概率值>=最小值)。\r\n"; + } + } + + if(vmaxValue>Double.valueOf(vdeviationLimit)||vmaxValueDouble.valueOf(vdeviationLimit)||vminValueDouble.valueOf(vdeviationLimit)||vaveValueDouble.valueOf(vdeviationLimit)||vcp95Value limit) { +// if (!"".equals(tmpstrResultVdeviationdata)) +// tmpstrResultVdeviationdata += "、"; +// tmpstrResultVdeviationdata += tmpstrMap + "相"; +// } + + // 假如为空则所有的都满足 + if ("".equals(tmpstrResultVdeviationdata)) { + strResultVdeviationdata += "从上表中可以看出" + strLineBaseName + "A、B、C三相电压偏差满足国标限值("+ldeviationLimit+"%至"+vdeviationLimit+"%)的要求。"; + } else { + strAnalysis += tmpstrResultVdeviationdata + "电压偏差不满足国标限值("+vdeviationLimit+")的要求。"; + strResultVdeviationdata += "从上表中可以看出" + strLineBaseName + tmpstrResultVdeviationdata + + "电压偏差不满足国标限值("+ldeviationLimit+"%至"+vdeviationLimit+"%)的要求。"; + } + + reportmap.put("$ResultVdeviationdata$", strResultVdeviationdata); + reportmap.put("$ResultVdeviationdataValue$", strResultVdeviationdataValue); + strError += strResultVdeviationdataValue; + + /************************************************************** + **** 频率偏差 + ***************************************************************/ + ReportValue valueOfFreValue = this.listFrequency.get(1).getList().get(0); + // 获取频率偏差国标限值 + String valueOfFreLimit = judgeNull(this.listFrequency.get(1).getOverLimit()); + reportmap.put("$FRE_L$", valueOfFreLimit); + String strResultFre = ""; + String tmpstrResultFre = ""; + String strResultFreValue = ""; + + reportmap.put("$FREX$", judgeNull(valueOfFreValue.getFmaxValue())); + reportmap.put("$FREN$", judgeNull(valueOfFreValue.getMinValue())); + reportmap.put("$FREE$", judgeNull(valueOfFreValue.getMeanValue())); + reportmap.put("$FRE%$", judgeNull(valueOfFreValue.getCp95Value())); + + /************************************ + **** 三张大表取值 + **************************************/ + reportmap.put("$FV0L$", valueOfFreLimit); + reportmap.put("$FV0X$", judgeNull(valueOfFreValue.getFmaxValue())); + reportmap.put("$FV0N$", judgeNull(valueOfFreValue.getMinValue())); + reportmap.put("$FV0E$", judgeNull(valueOfFreValue.getMeanValue())); + reportmap.put("$FV0%$", judgeNull(valueOfFreValue.getCp95Value())); + + try { + maxValue = Double.parseDouble(valueOfFreValue.getFmaxValue().toString()); + minValue = Double.parseDouble(valueOfFreValue.getMinValue().toString()); + aveValue = Double.parseDouble(valueOfFreValue.getMeanValue().toString()); + cp95Value = Double.parseDouble(valueOfFreValue.getCp95Value().toString()); + limit = Math.abs(Double.parseDouble(valueOfFreLimit)); + } catch (Exception e) { + strResultFreValue += "注意:从上表中可以看出" + strLineBaseName + "频率偏差数据存在异常(不是数值类型)。\r\n"; + } + + if (Math.abs(maxValue) > limit) { + tmpstrResultFre += "最大值为:" + valueOfFreValue.getFmaxValue().toString() + deviceUnit.getUnitFrequencyDev(); + } + if (Math.abs(minValue) > limit) { + tmpstrResultFre += "最小值为:" + valueOfFreValue.getMinValue().toString() + deviceUnit.getUnitFrequencyDev(); + } + if (Math.abs(aveValue) > limit) { + tmpstrResultFre += "平均值为:" + valueOfFreValue.getMeanValue().toString() + deviceUnit.getUnitFrequencyDev(); + } + if (Math.abs(cp95Value) > limit) { + tmpstrResultFre += "95%概率值为:" + valueOfFreValue.getCp95Value().toString() + deviceUnit.getUnitFrequencyDev(); + } + + if (!(maxValue >= minValue && maxValue >= aveValue && maxValue >= cp95Value)) { + strResultFreValue += "注意:从上表中可以看出" + strLineBaseName + + "频率偏差数据存在异常( 1、最大值>=最小值、平均值、95%概率值;2、平均值>=最小值;3、95%概率值>=最小值)。\r\n"; + } else if (aveValue < minValue) { + strResultFreValue += "注意:从上表中可以看出" + strLineBaseName + + "频率偏差数据存在异常( 1、最大值>=最小值、平均值、95%概率值;2、平均值>=最小值;3、95%概率值>=最小值)。\r\n"; + } else if (cp95Value < minValue) { + strResultFreValue += "注意:从上表中可以看出" + strLineBaseName + + "频率偏差数据存在异常( 1、最大值>=最小值、平均值、95%概率值;2、平均值>=最小值;3、95%概率值>=最小值)。\r\n"; + } + + if ("".equals(tmpstrResultFre)) { + // 三张大表取值 + reportmap.put("$FV0R$", "合格"); + strResultFre += "从上表中可以看出" + strLineBaseName + "频率偏差均满足国标限值(±" + valueOfFreLimit + deviceUnit.getUnitFrequencyDev() + ")的要求。"; + } else { + // 三张大表取值 + reportmap.put("$FV0R$", "不合格"); + strAnalysis += tmpstrResultFre + ",均不满足国标限值(±" + valueOfFreLimit + deviceUnit.getUnitFrequencyDev() + ")的要求。\r\n"; + strResultFre += "从上表中可以看出" + strLineBaseName + "频率偏差" + tmpstrResultFre + ",均不满足国标限值(±" + valueOfFreLimit + + deviceUnit.getUnitFrequencyDev() + ")的要求。\r\n"; + } + + reportmap.put("$ResultFre$", strResultFre); + reportmap.put("$ResultFreValue$", strResultFreValue); + strError += strResultFreValue; + + /************************************************************** + **** 三相电压不平衡度 + ***************************************************************/ + ReportValue valueOfThree = this.listThreephase.get(0).getList().get(0); + // 获取三相电压不平衡度国标限值 + String valueOfThreeLimit = judgeNull(this.listThreephase.get(0).getOverLimit()); + reportmap.put("$THE_L$", valueOfThreeLimit); + String strResultThree = ""; + String tmpstrResultThree = ""; + String strResultThreeValue = ""; + reportmap.put("$THEX$", judgeNull(valueOfThree.getFmaxValue())); + reportmap.put("$THEN$", judgeNull(valueOfThree.getMinValue())); + reportmap.put("$THEE$", judgeNull(valueOfThree.getMeanValue())); + reportmap.put("$THE%$", judgeNull(valueOfThree.getCp95Value())); + + /************************************ + **** 三张大表取值 + **************************************/ + reportmap.put("$TV0L$", valueOfThreeLimit); + reportmap.put("$TV0X$", judgeNull(valueOfThree.getFmaxValue())); + reportmap.put("$TV0N$", judgeNull(valueOfThree.getMinValue())); + reportmap.put("$TV0E$", judgeNull(valueOfThree.getMeanValue())); + reportmap.put("$TV0%$", judgeNull(valueOfThree.getCp95Value())); + + try { + maxValue = Double.parseDouble(valueOfThree.getFmaxValue().toString()); + minValue = Double.parseDouble(valueOfThree.getMinValue().toString()); + aveValue = Double.parseDouble(valueOfThree.getMeanValue().toString()); + cp95Value = Double.parseDouble(valueOfThree.getCp95Value().toString()); + limit = Double.parseDouble(valueOfThreeLimit); + } catch (Exception e) { + strResultThreeValue += "注意:从上表中可以看出" + strLineBaseName + "三相电压不平衡度数据存在异常(不是数值类型)。\r\n"; + } + if (cp95Value > limit) { + // 三张大表取值 + reportmap.put("$TV0R$", "不合格"); + tmpstrResultThree += "三相电压不平衡度95%概率值为:" + valueOfThree.getCp95Value().toString(); + } else { + // 三张大表取值 + reportmap.put("$TV0R$", "合格"); + } + + if (!(maxValue >= minValue && maxValue >= aveValue && maxValue >= cp95Value)) { + strResultThreeValue += "注意:从上表中可以看出" + strLineBaseName + + "三相电压不平衡度数据存在异常( 1、最大值>=最小值、平均值、95%概率值;2、平均值>=最小值;3、95%概率值>=最小值)。\r\n"; + } else if (aveValue < minValue) { + strResultThreeValue += "注意:从上表中可以看出" + strLineBaseName + + "三相电压不平衡度数据存在异常( 1、最大值>=最小值、平均值、95%概率值;2、平均值>=最小值;3、95%概率值>=最小值)。\r\n"; + } else if (cp95Value < minValue) { + strResultThreeValue += "注意:从上表中可以看出" + strLineBaseName + + "三相电压不平衡度数据存在异常( 1、最大值>=最小值、平均值、95%概率值;2、平均值>=最小值;3、95%概率值>=最小值)。\r\n"; + } + + if ("".equals(tmpstrResultThree)) { + strResultThree += "三相电压不平衡度根据国标标准测量结果以95%概率值作为判断是否合格的依据,从上表中可以看出" + strLineBaseName + tmpstrResultThree + + ",满足国标限值(" + valueOfThreeLimit + "%)的要求。"; + } else { + strAnalysis += tmpstrResultThree + ",不满足国标限值(" + valueOfThreeLimit + "%)的要求。"; + strResultThree += "三相电压不平衡度根据国标标准测量结果以95%概率值作为判断是否合格的依据,从上表中可以看出" + strLineBaseName + tmpstrResultThree + + ",不满足国标限值(" + valueOfThreeLimit + "%)的要求。"; + } + + reportmap.put("$ResultThree$", strResultThree); + reportmap.put("$ResultThreeValue$", strResultThreeValue); + strError += strResultThreeValue; + + /************************************************************** + **** 电压闪变 + ***************************************************************/ + // 获取电压长时闪变的限值 + String valueOfFlickerLimit = judgeNull(this.listFlicker.get(1).getOverLimit()); + reportmap.put("$PLT_L$", valueOfFlickerLimit); + String strResultFlicker = ""; + String tmpstrResultFlicker = ""; + String strResultFlickerValue = ""; + Double fmaxValue1 = 0.0; + Double fmaxValue2 = 0.0; + Double fmaxValue3 = 0.0; + Double flickerLimit = 0.0; + try { + fmaxValue1 = Double.parseDouble(plt1.getFmaxValue().toString()); + fmaxValue2 = Double.parseDouble(plt2.getFmaxValue().toString()); + fmaxValue3 = Double.parseDouble(plt3.getFmaxValue().toString()); + flickerLimit = Double.parseDouble(valueOfFlickerLimit); + } catch (Exception e) { + strResultFlickerValue += "注意:从上表中可以看出" + strLineBaseName + "长时闪变数据存在异常(不是数值类型)。\r\n"; + } + if (fmaxValue1 > flickerLimit) { + if (!"".equals(tmpstrResultFlicker)) + tmpstrResultFlicker += ","; + tmpstrResultFlicker += atype + "最大值为:" + plt1.getFmaxValue().toString(); + reportmap.put("$" + "L" + "V0R_" + "A" + "$", "不合格"); + } else { + reportmap.put("$" + "L" + "V0R_" + "A" + "$", "合格"); + } + + if (fmaxValue2 > flickerLimit) { + if (!"".equals(tmpstrResultFlicker)) + tmpstrResultFlicker += ","; + tmpstrResultFlicker += btype + "最大值为:" + plt2.getFmaxValue().toString(); + reportmap.put("$" + "L" + "V0R_" + "B" + "$", "不合格"); + } else { + reportmap.put("$" + "L" + "V0R_" + "B" + "$", "合格"); + } + + if (fmaxValue3 > flickerLimit && pttype != 2) { + if (!"".equals(tmpstrResultFlicker)) + tmpstrResultFlicker += ","; + tmpstrResultFlicker += ctype + "最大值为:" + plt3.getFmaxValue().toString(); + reportmap.put("$" + "L" + "V0R_" + "C" + "$", "不合格"); + } else { + reportmap.put("$" + "L" + "V0R_" + "C" + "$", "合格"); + } + + reportmap.put("$PSTX_A$", judgeNull(pst1.getFmaxValue())); + reportmap.put("$PSTN_A$", judgeNull(pst1.getMinValue())); + reportmap.put("$PSTE_A$", judgeNull(pst1.getMeanValue())); + reportmap.put("$PST%_A$", judgeNull(pst1.getCp95Value())); + reportmap.put("$PSTX_B$", judgeNull(pst2.getFmaxValue())); + reportmap.put("$PSTN_B$", judgeNull(pst2.getMinValue())); + reportmap.put("$PSTE_B$", judgeNull(pst2.getMeanValue())); + reportmap.put("$PST%_B$", judgeNull(pst2.getCp95Value())); + if (pttype != 2) { + reportmap.put("$PSTX_C$", judgeNull(pst3.getFmaxValue())); + reportmap.put("$PSTN_C$", judgeNull(pst3.getMinValue())); + reportmap.put("$PSTE_C$", judgeNull(pst3.getMeanValue())); + reportmap.put("$PST%_C$", judgeNull(pst3.getCp95Value())); + } else { + reportmap.put("$PSTX_C$", "-"); + reportmap.put("$PSTN_C$", "-"); + reportmap.put("$PSTE_C$", "-"); + reportmap.put("$PST%_C$", "-"); + } + + reportmap.put("$PLTX_A$", judgeNull(plt1.getFmaxValue())); + reportmap.put("$PLTN_A$", judgeNull(plt1.getMinValue())); + reportmap.put("$PLTE_A$", judgeNull(plt1.getMeanValue())); + reportmap.put("$PLT%_A$", judgeNull(plt1.getCp95Value())); + reportmap.put("$PLTX_B$", judgeNull(plt2.getFmaxValue())); + reportmap.put("$PLTN_B$", judgeNull(plt2.getMinValue())); + reportmap.put("$PLTE_B$", judgeNull(plt2.getMeanValue())); + reportmap.put("$PLT%_B$", judgeNull(plt2.getCp95Value())); + if (pttype != 2) { + reportmap.put("$PLTX_C$", judgeNull(plt3.getFmaxValue())); + reportmap.put("$PLTN_C$", judgeNull(plt3.getMinValue())); + reportmap.put("$PLTE_C$", judgeNull(plt3.getMeanValue())); + reportmap.put("$PLT%_C$", judgeNull(plt3.getCp95Value())); + } else { + reportmap.put("$PLTX_C$", "-"); + reportmap.put("$PLTN_C$", "-"); + reportmap.put("$PLTE_C$", "-"); + reportmap.put("$PLT%_C$", "-"); + } + reportmap.put("$PLT_L$", valueOfFlickerLimit); + + /************************************ + **** 三张大表取值 + **************************************/ + reportmap.put("$" + "L" + "V0" + "X" + "_" + "A" + "$", judgeNull(plt1.getFmaxValue())); + reportmap.put("$" + "L" + "V0" + "E" + "_" + "A" + "$", judgeNull(plt1.getMeanValue())); + reportmap.put("$" + "L" + "V0" + "N" + "_" + "A" + "$", judgeNull(plt1.getMinValue())); + reportmap.put("$" + "L" + "V0" + "%" + "_" + "A" + "$", judgeNull(plt1.getCp95Value())); + reportmap.put("$" + "L" + "V0" + "X" + "_" + "B" + "$", judgeNull(plt2.getFmaxValue())); + reportmap.put("$" + "L" + "V0" + "E" + "_" + "B" + "$", judgeNull(plt2.getMeanValue())); + reportmap.put("$" + "L" + "V0" + "N" + "_" + "B" + "$", judgeNull(plt2.getMinValue())); + reportmap.put("$" + "L" + "V0" + "%" + "_" + "B" + "$", judgeNull(plt2.getCp95Value())); + reportmap.put("$" + "L" + "V0" + "X" + "_" + "C" + "$", judgeNull(plt3.getFmaxValue())); + reportmap.put("$" + "L" + "V0" + "E" + "_" + "C" + "$", judgeNull(plt3.getMeanValue())); + reportmap.put("$" + "L" + "V0" + "N" + "_" + "C" + "$", judgeNull(plt3.getMinValue())); + reportmap.put("$" + "L" + "V0" + "%" + "_" + "C" + "$", judgeNull(plt3.getCp95Value())); + reportmap.put("$LV0%_L$", valueOfFlickerLimit); + + reportmap.put("$" + "S" + "V0" + "X" + "_" + "A" + "$", judgeNull(pst1.getFmaxValue())); + reportmap.put("$" + "S" + "V0" + "E" + "_" + "A" + "$", judgeNull(pst1.getMeanValue())); + reportmap.put("$" + "S" + "V0" + "N" + "_" + "A" + "$", judgeNull(pst1.getMinValue())); + reportmap.put("$" + "S" + "V0" + "%" + "_" + "A" + "$", judgeNull(pst1.getCp95Value())); + reportmap.put("$" + "S" + "V0" + "X" + "_" + "B" + "$", judgeNull(pst2.getFmaxValue())); + reportmap.put("$" + "S" + "V0" + "E" + "_" + "B" + "$", judgeNull(pst2.getMeanValue())); + reportmap.put("$" + "S" + "V0" + "N" + "_" + "B" + "$", judgeNull(pst2.getMinValue())); + reportmap.put("$" + "S" + "V0" + "%" + "_" + "B" + "$", judgeNull(pst2.getCp95Value())); + reportmap.put("$" + "S" + "V0" + "X" + "_" + "C" + "$", judgeNull(pst3.getFmaxValue())); + reportmap.put("$" + "S" + "V0" + "E" + "_" + "C" + "$", judgeNull(pst3.getMeanValue())); + reportmap.put("$" + "S" + "V0" + "N" + "_" + "C" + "$", judgeNull(pst3.getMinValue())); + reportmap.put("$" + "S" + "V0" + "%" + "_" + "C" + "$", judgeNull(pst3.getCp95Value())); + + if ("".equals(tmpstrResultFlicker)) { + strResultFlicker += "电压长时闪变根据国标标准测量结果以最大值、最小值、95%概率值作为判断是否合格的依据,从上表中可以看出" + strLineBaseName + "长时闪变" + + tmpstrResultFlicker + ",其满足国标限值(" + valueOfFlickerLimit + ")的要求。"; + } else { + strAnalysis += "长时闪变" + tmpstrResultFlicker + ",其不满足国标限值(" + valueOfFlickerLimit + ")的要求。"; + strResultFlicker += "电压长时闪变根据国标标准测量结果以最大值、最小值、95%概率值作为判断是否合格的依据,从上表中可以看出" + strLineBaseName + "长时闪变" + + tmpstrResultFlicker + ",其不满足国标限值(" + valueOfFlickerLimit + ")的要求。"; + } + + reportmap.put("$ResultFlicker$", strResultFlicker); + reportmap.put("$ResultFlickerValue$", strResultFlickerValue); + strError += strResultFlickerValue; + + /************************************************************** + **** 电压含有率 + ***************************************************************/ + String strResultVoltageRate = ""; + String tmpstrResultVoltageRate = ""; + String strResultVoltageRateValue = ""; + String strCurrentA, strCurrentB, strCurrentC, strLimit; + // 获取25次谐波 + for (int i = 1; i < 25; i++) { + String strMap = "$RV"; + String strCurrentRate = strMap + (i + 1) + "%"; + + // 基波电压含有率 + strCurrentA = judgeNull((this.listVoltageRate.get(i).getList().get(0)).getCp95Value()); + strCurrentB = judgeNull((this.listVoltageRate.get(i).getList().get(1)).getCp95Value()); + strCurrentC = judgeNull((this.listVoltageRate.get(i).getList().get(2)).getCp95Value()); + strLimit = judgeNull(this.listVoltageRate.get(i).getOverLimit()); + + reportmap.put(strCurrentRate + "_A$", strCurrentA); + reportmap.put(strCurrentRate + "_B$", strCurrentB); + if (pttype != 2) { + reportmap.put(strCurrentRate + "_C$", strCurrentC); + } else { + reportmap.put(strCurrentRate + "_C$", "-"); + } + reportmap.put(strCurrentRate + "_L$", strLimit); + + /************************************ + **** 三张大表取值 + **************************************/ + reportmap.put("$CV" + (i + 1) + "X_A$", + judgeNull((this.listVoltageRate.get(i).getList().get(0)).getFmaxValue())); + reportmap.put("$CV" + (i + 1) + "X_B$", + judgeNull((this.listVoltageRate.get(i).getList().get(1)).getFmaxValue())); + + reportmap.put("$CV" + (i + 1) + "N_A$", + judgeNull((this.listVoltageRate.get(i).getList().get(0)).getMinValue())); + reportmap.put("$CV" + (i + 1) + "N_B$", + judgeNull((this.listVoltageRate.get(i).getList().get(1)).getMinValue())); + + reportmap.put("$CV" + (i + 1) + "E_A$", + judgeNull((this.listVoltageRate.get(i).getList().get(0)).getMeanValue())); + reportmap.put("$CV" + (i + 1) + "E_B$", + judgeNull((this.listVoltageRate.get(i).getList().get(1)).getMeanValue())); + + if (pttype != 2) { + reportmap.put("$CV" + (i + 1) + "X_C$", + judgeNull((this.listVoltageRate.get(i).getList().get(2)).getFmaxValue())); + reportmap.put("$CV" + (i + 1) + "N_C$", + judgeNull((this.listVoltageRate.get(i).getList().get(2)).getMinValue())); + reportmap.put("$CV" + (i + 1) + "E_C$", + judgeNull((this.listVoltageRate.get(i).getList().get(2)).getMeanValue())); + reportmap.put("$CV" + (i + 1) + "%_C$", strCurrentC); + } else { + reportmap.put("$CV" + (i + 1) + "X_C$", "-"); + reportmap.put("$CV" + (i + 1) + "N_C$", "-"); + reportmap.put("$CV" + (i + 1) + "E_C$", "-"); + reportmap.put("$CV" + (i + 1) + "%_C$", "-"); + } + + reportmap.put("$CV" + (i + 1) + "%_A$", strCurrentA); + reportmap.put("$CV" + (i + 1) + "%_B$", strCurrentB); + reportmap.put("$CV" + (i + 1) + "L$", strLimit); + + try { + maxValue = Double.parseDouble(strCurrentA); + minValue = Double.parseDouble(strCurrentB); + aveValue = Double.parseDouble(strCurrentC); + limit = Double.parseDouble(strLimit); + } catch (Exception e) { + strResultVoltageRateValue += "注意:从上表中可以看出" + strLineBaseName + (i+1)+"次谐波电压含有率95%概率值数据存在异常(不是数值类型)。\r\n"; + } + + String tmpstrResult = ""; + if (maxValue > limit) { + if (!"".equals(tmpstrResult)) { + tmpstrResult += "、"; + } + tmpstrResult += "A"; + // 三张大表取值 + reportmap.put("$CV" + (i + 1) + "R_A$", "不合格"); + } else { + // 三张大表取值 + reportmap.put("$CV" + (i + 1) + "R_A$", "合格"); + } + if (minValue > limit) { + if (!"".equals(tmpstrResult)) { + tmpstrResult += "、"; + } + tmpstrResult += "B"; + // 三张大表取值 + reportmap.put("$CV" + (i + 1) + "R_B$", "不合格"); + } else { + // 三张大表取值 + reportmap.put("$CV" + (i + 1) + "R_B$", "合格"); + } + if (aveValue > limit) { + if (!"".equals(tmpstrResult)) { + tmpstrResult += "、"; + } + tmpstrResult += "C"; + // 三张大表取值 + reportmap.put("$CV" + (i + 1) + "R_C$", "不合格"); + } else { + // 三张大表取值 + reportmap.put("$CV" + (i + 1) + "R_C$", "合格"); + } + // 判断单个结论是否存在 + if (!"".equals(tmpstrResult)) { + tmpstrResultVoltageRate += (i + 1) + "次谐波电压含有率95%概率值" + tmpstrResult + ";\r\n"; + } + } + + // 假如为空则所有的都满足 + if ("".equals(tmpstrResultVoltageRate)) { + strResultVoltageRate += "从上表中可以看出" + strLineBaseName + "2-25次谐波电压含有率95%概率值均满足国标限值要求。\r\n"; + } else { + strAnalysis += tmpstrResultVoltageRate + "2-25次谐波电压含有率95%概率值均不满足国标限值要求。\r\n"; + strResultVoltageRate += "从上表中可以看出" + strLineBaseName + "\r\n"+tmpstrResultVoltageRate + "均不满足国标限值要求。\r\n"; + } + + /************************************************************** + **** 电压总谐波畸变率(THD) + ***************************************************************/ + ReportValue distortion1 = this.listDistortion.get(0).getList().get(0); + ReportValue distortion2 = this.listDistortion.get(0).getList().get(1); + ReportValue distortion3 = this.listDistortion.get(0).getList().get(2); + String distortionLimit = judgeNull(this.listDistortion.get(0).getOverLimit()); + reportmap.put("$DV0%_L$", distortionLimit); + + String strResultDistortion = ""; + String tmpstrResultDistortion = ""; + String strResultDistortionValue = ""; + + reportmap.put("$DV0%_A$", judgeNull(distortion1.getCp95Value())); + reportmap.put("$DV0%_B$", judgeNull(distortion2.getCp95Value())); + reportmap.put("$DV0%_C$", judgeNull(distortion3.getCp95Value())); + + /************************************ + **** 三张大表取值 + **************************************/ + reportmap.put("$TV0X_L$", distortionLimit); + reportmap.put("$TV0X_A$", judgeNull(distortion1.getFmaxValue())); + reportmap.put("$TV0E_A$", judgeNull(distortion1.getMeanValue())); + reportmap.put("$TV0N_A$", judgeNull(distortion1.getMinValue())); + reportmap.put("$TV0%_A$", judgeNull(distortion1.getCp95Value())); + + reportmap.put("$TV0X_B$", judgeNull(distortion2.getFmaxValue())); + reportmap.put("$TV0E_B$", judgeNull(distortion2.getMeanValue())); + reportmap.put("$TV0N_B$", judgeNull(distortion2.getMinValue())); + reportmap.put("$TV0%_B$", judgeNull(distortion2.getCp95Value())); + + reportmap.put("$TV0X_C$", judgeNull(distortion3.getFmaxValue())); + reportmap.put("$TV0E_C$", judgeNull(distortion3.getMeanValue())); + reportmap.put("$TV0N_C$", judgeNull(distortion3.getMinValue())); + reportmap.put("$TV0%_C$", judgeNull(distortion3.getCp95Value())); + + // 值错误判断 + try { + cp95ValueA = Math.abs(Double.parseDouble(distortion1.getCp95Value().toString())); + cp95ValueB = Math.abs(Double.parseDouble(distortion2.getCp95Value().toString())); + cp95ValueC = Math.abs(Double.parseDouble(distortion3.getCp95Value().toString())); + limit = Math.abs(Double.parseDouble(distortionLimit)); + } catch (Exception e) { + strResultDistortionValue += "注意:从上表中可以看出" + strLineBaseName + "电压总谐波畸变率(THD)数据存在异常(不是数值类型)。\r\n"; + } + // 限值判断 + if (cp95ValueA > limit) { + if (!"".equals(tmpstrResultDistortion)) { + tmpstrResultDistortion += "、"; + } + tmpstrResultDistortion += atype; + // 三张大表取值 + reportmap.put("$TV0R_A$", "不合格"); + } else { + // 三张大表取值 + reportmap.put("$TV0R_A$", "合格"); + } + if (cp95ValueB > limit) { + if (!"".equals(tmpstrResultDistortion)) { + tmpstrResultDistortion += "、"; + } + tmpstrResultDistortion += btype; + // 三张大表取值 + reportmap.put("$TV0R_B$", "不合格"); + } else { + // 三张大表取值 + reportmap.put("$TV0R_B$", "合格"); + } + if (cp95ValueC > limit && pttype != 2) { + if (!"".equals(tmpstrResultDistortion)) { + tmpstrResultDistortion += "、"; + } + tmpstrResultDistortion += ctype; + // 三张大表取值 + reportmap.put("$TV0R_C$", "不合格"); + } else { + // 三张大表取值 + reportmap.put("$TV0R_C$", "合格"); + } + strError += strResultVoltageRateValue + strResultDistortionValue; + // 假如为空则所有的都满足 + if ("".equals(tmpstrResultDistortion) && "".equals(strResultDistortionValue)) { + strResultDistortion += "电压总谐波畸变率(THD)95%概率值均满足国标限值要求。\r\n"; + reportmap.put("$ResultVoltageRateValue$", ""); + } else { + strAnalysis += "电压总谐波畸变率(THD)95%概率值" + tmpstrResultDistortion + "均不满足国标限值要求。\r\n"; + strResultDistortion += "电压总谐波畸变率(THD)95%概率值" + tmpstrResultDistortion + "均不满足国标限值要求。\r\n"; + reportmap.put("$ResultVoltageRateValue$", strError); + } + reportmap.put("$ResultVoltageRate$", strResultVoltageRate + strResultDistortion); + + + + + /************************************************************** + **** 谐波电流幅值 + ***************************************************************/ + String strResultCurrent = ""; + String tmpstrResultCurrent = ""; + String strResultCurrentValue = ""; + // 获取25次谐波 + for (int i = 1; i < 25; i++) { + String strMap = "$RI"; + String strCurrent = strMap + (i + 1) + "%"; + + // 基波电压含有率 + strCurrentA = judgeNull(this.listICurrent.get(i).getList().get(0).getCp95Value()); + strCurrentB = judgeNull(this.listICurrent.get(i).getList().get(1).getCp95Value()); + strCurrentC = judgeNull(this.listICurrent.get(i).getList().get(2).getCp95Value()); + strLimit = judgeNull(this.listICurrent.get(i).getOverLimit()); + + reportmap.put(strCurrent + "_A$", strCurrentA); + reportmap.put(strCurrent + "_B$", strCurrentB); + reportmap.put(strCurrent + "_C$", strCurrentC); + reportmap.put(strCurrent + "_L$", strLimit); + + /************************************ + **** 三张大表取值 + **************************************/ + reportmap.put("$CI" + (i + 1) + "X_A$", judgeNull(this.listICurrent.get(i).getList().get(0).getFmaxValue())); + reportmap.put("$CI" + (i + 1) + "X_B$", judgeNull(this.listICurrent.get(i).getList().get(1).getFmaxValue())); + reportmap.put("$CI" + (i + 1) + "X_C$", judgeNull(this.listICurrent.get(i).getList().get(2).getFmaxValue())); + + reportmap.put("$CI" + (i + 1) + "N_A$", judgeNull(this.listICurrent.get(i).getList().get(0).getMinValue())); + reportmap.put("$CI" + (i + 1) + "N_B$", judgeNull(this.listICurrent.get(i).getList().get(1).getMinValue())); + reportmap.put("$CI" + (i + 1) + "N_C$", judgeNull(this.listICurrent.get(i).getList().get(2).getMinValue())); + + reportmap.put("$CI" + (i + 1) + "E_A$", judgeNull(this.listICurrent.get(i).getList().get(0).getMeanValue())); + reportmap.put("$CI" + (i + 1) + "E_B$", judgeNull(this.listICurrent.get(i).getList().get(1).getMeanValue())); + reportmap.put("$CI" + (i + 1) + "E_C$", judgeNull(this.listICurrent.get(i).getList().get(2).getMeanValue())); + + reportmap.put("$CI" + (i + 1) + "%_A$", strCurrentA); + reportmap.put("$CI" + (i + 1) + "%_B$", strCurrentB); + reportmap.put("$CI" + (i + 1) + "%_C$", strCurrentC); + reportmap.put("$CI" + (i + 1) + "L$", strLimit); + + try { + maxValue = Double.parseDouble(strCurrentA); + minValue = Double.parseDouble(strCurrentB); + aveValue = Double.parseDouble(strCurrentC); + limit = Double.parseDouble(strLimit); + } catch (Exception e) { + strResultCurrentValue += "注意:从上表中可以看出" + strLineBaseName +(i + 1)+ "次谐波电流幅值95%概率值数据存在异常(不是数值类型)。\r\n"; + } + + String tmpstrResult = ""; + if (maxValue > limit) { + if (!"".equals(tmpstrResult)) { + tmpstrResult += "、"; + } + tmpstrResult += "A"; + // 三张大表取值 + reportmap.put("$CI" + (i + 1) + "R_A$", "不合格"); + } else { + // 三张大表取值 + reportmap.put("$CI" + (i + 1) + "R_A$", "合格"); + } + if (minValue > limit) { + if (!"".equals(tmpstrResult)) { + tmpstrResult += "、"; + } + tmpstrResult += "B"; + // 三张大表取值 + reportmap.put("$CI" + (i + 1) + "R_B$", "不合格"); + } else { + // 三张大表取值 + reportmap.put("$CI" + (i + 1) + "R_B$", "合格"); + } + if (aveValue > limit) { + if (!"".equals(tmpstrResult)) { + tmpstrResult += "、"; + } + tmpstrResult += "C"; + // 三张大表取值 + reportmap.put("$CI" + (i + 1) + "R_C$", "不合格"); + } else { + // 三张大表取值 + reportmap.put("$CI" + (i + 1) + "R_C$", "合格"); + } + // 判断单个结论是否存在 + if (!"".equals(tmpstrResult)) { + tmpstrResultCurrent += (i + 1) + "次谐波电流幅值95%概率值" + tmpstrResult + ";\r\n"; + } + } + strError += strResultCurrentValue; + // 假如为空则所有的都满足 + if ("".equals(tmpstrResultCurrent) && "".equals(strResultCurrentValue)) { + strResultCurrent += "从上表中可以看出" + strLineBaseName + "\r\n2-25次谐波电流幅值95%概率值均满足国标限值要求。\r\n"; + reportmap.put("$ResultCurrentValue$", ""); + } else { + strAnalysis += tmpstrResultCurrent + "均不满足国标限值要求。"; + strResultCurrent += "从上表中可以看出" + strLineBaseName + tmpstrResultCurrent + "均不满足国标限值要求。\r\n"; + reportmap.put("$ResultCurrentValue$", strError); + + } + + reportmap.put("$ResultCurrent$", strResultCurrent); + + // 测试结果填写 + reportmap.put("$ResultTitle$", String.format("通过对(%s——%s)时间段内%s电能质量统计数据分析后得出以下结论:", + new String[]{DateUtil.format(startDate, "yyyy年MM月dd日 HH时mm分ss秒"), + DateUtil.format(endDate, "yyyy年MM月dd日 HH时mm分ss秒"), strLineBaseName})); + + // 电压偏差 + reportmap.put("$Result_VD$", String.format("(1)电压偏差:%s", new String[]{strResultVdeviationdata})); + // 频率偏差 + reportmap.put("$Result_FRE$", String.format("(2)频率偏差:%s", new String[]{strResultFre})); + // 三相电压不平衡度 + reportmap.put("$Result_THE$", String.format("(3)三相电压不平衡度:%s", new String[]{strResultThree})); + // 电压长时闪变 + reportmap.put("$Result_FIC$", String.format("(4)电压长时闪变:%s", new String[]{strResultFlicker})); + // 谐波电压 + reportmap.put("$Result_VOL$", String.format("(5)谐波电压:%s", new String[]{strResultVoltageRate})); + // 谐波电流 + reportmap.put("$Result_CUR$", String.format("(6)谐波电流:%s", new String[]{strResultCurrent})); + // 分析建议填写 + if (!"".equals(strAnalysis) || !"".equals(strError)) { + // 分析建议 + reportmap.put("$Analysis$", "根据统计数据结果分析,监测点为:" + name + "," + strAnalysis + strError); + } else { + // 分析建议 + reportmap.put("$Analysis$", "根据统计数据结果分析,监测点为:" + name + ",电能质量数据满足国标限值要求。"); + } + + /************************************ + **** 三张大表取值 有功:0-11 无功:12-23 视在:24-31 基波有功汇总:32-35 基波无功汇总:36-39 + * 基波视在汇总:40-43 功率因数:44-46 + **************************************/ + ReportValue powerDto1 = this.listPower.get(0).getList().get(3); + ReportValue powerDto2 = this.listPower.get(1).getList().get(3); + ReportValue powerDto3 = this.listPower.get(2).getList().get(3); + ReportValue powerDto4 = this.listPower.get(3).getList().get(3); + reportmap.put("$BF0X$", judgeNull(powerDto1.getFmaxValue())); + reportmap.put("$BF0N$", judgeNull(powerDto1.getMinValue())); + reportmap.put("$BF0E$", judgeNull(powerDto1.getMeanValue())); + + reportmap.put("$NF0X$", judgeNull(powerDto2.getFmaxValue())); + reportmap.put("$NF0N$", judgeNull(powerDto2.getMinValue())); + reportmap.put("$NF0E$", judgeNull(powerDto2.getMeanValue())); + + reportmap.put("$SF0X$", judgeNull(powerDto3.getFmaxValue())); + reportmap.put("$SF0N$", judgeNull(powerDto3.getMinValue())); + reportmap.put("$SF0E$", judgeNull(powerDto3.getMeanValue())); + + reportmap.put("$YF0X$", judgeNull(powerDto4.getFmaxValue())); + reportmap.put("$YF0N$", judgeNull(powerDto4.getMinValue())); + reportmap.put("$YF0E$", judgeNull(powerDto4.getMeanValue())); + // 报告时分秒格式 + formatter = new SimpleDateFormat("yyyyMMddHHmmss"); + + String reportFileUrl = ""; + try { + String fileName = name + formatter.format(currentTime) + ".docx"; + if(ObjectUtil.isNotNull(isUrl)){ + if (isUrl) { + reportFileUrl = wordUtil2.getReportFileUrl(rtfPath, name + formatter.format(currentTime) + ".docx",null ,reportmap); + } + } + wordUtil2.getWord(rtfPath, reportmap, fileName,null, response); + } catch (Exception e) { + log.error("获取报告发生异常,异常是" + e.getMessage()); + } + } + + /** + * 数据单位信息 重组 + * + * @param deviceUnit 数据单位对象 + * @return + */ + private Map unitMap(DeviceUnitCommDTO deviceUnit) { + List dictData = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEVICE_UNIT.getCode()).getData(); + Map unit = new HashMap<>(16); + List list = dictData.stream().map(DictData::getCode).collect(Collectors.toList()); + for (String s : list) { + //有效值 + if (s.equals(DicDataEnum.EFFECTIVE.getCode())) { + unit.put("$" + s + "_i$", deviceUnit.getIeffective()); + unit.put("$" + s + "_v$", deviceUnit.getLineVoltage()); + } + //功率 + if (s.equals(DicDataEnum.POWER.getCode())) { + unit.put("$" + s + "_p$", deviceUnit.getTotalActiveP()); + unit.put("$" + s + "_q$", deviceUnit.getTotalNoP()); + unit.put("$" + s + "_s$", deviceUnit.getTotalViewP()); + } + //畸变率 + if (s.equals(DicDataEnum.DISTORTION.getCode())) { + unit.put("$" + s + "_v$", deviceUnit.getVdistortion()); + } + //电压偏差 + if (s.equals(DicDataEnum.VOLTAGE.getCode())) { + unit.put("$" + s + "_v$", deviceUnit.getVoltageDev()); + } + //频率 + if (s.equals(DicDataEnum.UNIT_FREQUENCY.getCode())) { + unit.put("$" + s + "_freq$", deviceUnit.getUnitFrequency()); + unit.put("$" + s + "_freqDev$", deviceUnit.getUnitFrequencyDev()); + } + //三项不平衡度 + if (s.equals(DicDataEnum.UNBALANCE.getCode())) { + unit.put("$" + s + "_v$", "%"); + unit.put("$" + s + "_vPos$", deviceUnit.getPositiveV()); + unit.put("$" + s + "_vNeg$", deviceUnit.getNoPositiveV()); + unit.put("$" + s + "_vZero$", deviceUnit.getNoPositiveV()); + unit.put("$" + s + "_i$", "%"); + unit.put("$" + s + "_iPos$", "A"); + unit.put("$" + s + "_iNeg$", "A"); + unit.put("$" + s + "_iZero$", "A"); + } + //基波 + if (s.equals(DicDataEnum.FUND.getCode())) { + unit.put("$" + s + "_i$", deviceUnit.getIfund()); + unit.put("$" + s + "_v$", deviceUnit.getVfundEffective()); + + } + } + return unit; + } + + + /** + * 解析base64,返回图片所在路径 + */ + @SuppressWarnings("restriction") + private String decodeBase64(byte[] base64Info) { + if (base64Info.length == 0) { + return null; + } + BASE64Encoder decoder = new BASE64Encoder(); + + return decoder.encode(base64Info); + } + + private void transformData(List list, List listValue, List listOverlimit, boolean... b) { + int offset = b[0] ? 3 : 1; + offset = (b.length == 2 && !b[1]) ? 4 : offset; + int i = 0; + + for (int index = 0; index < listValue.size(); index += offset) { + if (i == listOverlimit.size()) { + break; + } + ReportTarget reportTarget = new ReportTarget(); + reportTarget.setList(listValue.subList(index, index + offset)); + Float overLimit = listOverlimit.get(i).getOverLimit(); + reportTarget.setOverLimit(overLimit); + + switch (listOverlimit.get(i).getCode()) { + case 1: + for (int k = 0; k < reportTarget.getList().size(); k++) { + if (null == reportTarget.getList().get(k).getFmaxValue()) { + break; + } else if (reportTarget.getList().get(k).getFmaxValue().floatValue() > overLimit.floatValue()) { + reportTarget.setPass(EnumPass.NOPASS.getCode()); + break; + } else { + reportTarget.setPass(EnumPass.PASS.getCode()); + } + } + break; + case 2: + for (int k = 0; k < reportTarget.getList().size(); k++) { + if (null == reportTarget.getList().get(k).getMinValue()) { + break; + } else if (reportTarget.getList().get(k).getMinValue().floatValue() > overLimit.floatValue()) { + reportTarget.setPass(EnumPass.NOPASS.getCode()); + break; + } else { + reportTarget.setPass(EnumPass.PASS.getCode()); + } + } + break; + case 3: + for (int k = 0; k < reportTarget.getList().size(); k++) { + if (null == reportTarget.getList().get(k).getMeanValue()) { + break; + } else if (reportTarget.getList().get(k).getMeanValue().floatValue() > overLimit.floatValue()) { + reportTarget.setPass(EnumPass.NOPASS.getCode()); + break; + } else { + reportTarget.setPass(EnumPass.PASS.getCode()); + } + } + break; + case 4: + for (int k = 0; k < reportTarget.getList().size(); k++) { + if (null == reportTarget.getList().get(k).getCp95Value()) { + break; + } else if (reportTarget.getList().get(k).getCp95Value().floatValue() > overLimit.floatValue()) { + reportTarget.setPass(EnumPass.NOPASS.getCode()); + break; + } else { + reportTarget.setPass(EnumPass.PASS.getCode()); + } + } + break; + default: + break; + } + + i++; + list.add(reportTarget); + } + } + + /** + * 基波幅值 + */ + public void getVirtualData(ReportQueryParam param) { + + List listVirtual = reportService.getVirtualData(param); + + List list = new ArrayList<>(); + + for (int i = 0; i < 3; i++) { + Pass pass = new Pass(null); + list.add(pass); + } + + this.listVirtual = new ArrayList<>(); + + transformData(this.listVirtual, listVirtual, list, true); + + + } + + /** + * 功率 + */ + public void getPowerData(ReportQueryParam param) { + List listPower = reportService.getPowerData(param); + + List list = new ArrayList<>(); + + for (int i = 0; i < 4; i++) { + Pass pass = new Pass(null); + list.add(pass); + } + this.listPower = new ArrayList<>(); + transformData(this.listPower, listPower, list, true, false); + } + + /** + * 闪变 + */ + public void getFlicker(ReportQueryParam param, OverLimitInfoCommDTO overLimit) { + List listFlicker = reportService.getFlickerData(param); + List list = new ArrayList<>(); + for (int i = 0; i < 2; i++) { + Pass pass; + if (i == 1) { + pass = new Pass(overLimit.getFlicker(), EnumPass.MAX.getCode()); + } else { + pass = new Pass(null); + } + list.add(pass); + } + this.listFlicker = new ArrayList<>(); + transformData(this.listFlicker, listFlicker, list, true); + } + + /** + * 电压偏差 + */ + public void getVdeviation(ReportQueryParam param, OverLimitInfoCommDTO overLimit) { + List listVdeviation = reportService.getVdeviation(param); + List list = new ArrayList<>(); +// for (int i = 0; i < 2; i++) { + Pass pass; + pass = new Pass(overLimit.getVoltageDev(), EnumPass.MAX.getCode()); + list.add(pass); + + Pass pass1; + pass1 = new Pass(overLimit.getUvoltageDev(), EnumPass.MIN.getCode()); + list.add(pass1); +// } + this.listVdeviation = new ArrayList<>(); + transformData(this.listVdeviation, listVdeviation, list, true); + } + + /** + * 畸变率 + */ + public void getDistortion(ReportQueryParam param, OverLimitInfoCommDTO overLimit) { + List listDistortion = reportService.getDistortionData(param); + List list = new ArrayList<>(); + for (int i = 0; i < 2; i++) { + Pass pass; + + if (i == 0) { + pass = new Pass(overLimit.getUaberrance(), EnumPass.MAX.getCode()); + } else { + pass = new Pass(null); + } + + list.add(pass); + } + this.listDistortion = new ArrayList<>(); + transformData(this.listDistortion, listDistortion, list, true); + } + + /** + * 频率 + */ + public void getFre(ReportQueryParam param, OverLimitInfoCommDTO overLimit) { + List listFrequency = reportService.getFrequencyData(param); + + List list = new ArrayList<>(); + + for (int i = 0; i < 2; i++) { + Pass pass; + if (i == 1) { + pass = new Pass(overLimit.getFreqDev(), EnumPass.MAX.getCode()); + } else { + pass = new Pass(null); + } + list.add(pass); + } + + this.listFrequency = new ArrayList<>(); + transformData(this.listFrequency, listFrequency, list, false); + } + + + /** + * 三相不平衡 + */ + public void getThreePhase(ReportQueryParam param, OverLimitInfoCommDTO overLimit) { + List listThreephase = reportService.getThreephase(param); + + List list = new ArrayList<>(); + + for (int i = 0; i < 8; i++) { + Pass pass; + + if (i == 0) { + pass = new Pass(overLimit.getUbalance(), EnumPass.CP95.getCode()); + } else { + pass = new Pass(null); + } + + list.add(pass); + } + + this.listThreephase = new ArrayList<>(); + transformData(this.listThreephase, listThreephase, list, false); + } + + + /** + * 谐波电流 + */ + public void getCurrentRate(ReportQueryParam param, OverLimitInfoCommDTO overLimit) { + List listICurrent = reportService.getICurrent(param); + + List list = new ArrayList<>(); + List iHarmList = getIHarmList(overLimit); + for (int i = 0; i < 50; i++) { + Pass pass; + if (i < iHarmList.size() + 1 && i > 0) { + pass = new Pass(iHarmList.get(i - 1), + EnumPass.CP95.getCode()); + } else { + pass = new Pass(null); + } + list.add(pass); + } + + this.listICurrent = new ArrayList<>(); + transformData(this.listICurrent, listICurrent, list, true); + } + + /** + * 谐波电压 + */ + public void getVoltageRate(ReportQueryParam param, OverLimitInfoCommDTO overLimit) { + List listVoltageRate = reportService.getVoltageRate(param); + + List list = new ArrayList<>(); + List vHarmList = getVHarmList(overLimit); + for (int i = 0; i < 51; i++) { + Pass pass; + + if (i == 0) { + pass = new Pass(null); + } else if (i == 50) { + pass = new Pass(overLimit.getUaberrance(), EnumPass.MAX.getCode()); + } else if (i < vHarmList.size() + 1) { + pass = new Pass(vHarmList.get(i - 1), + EnumPass.CP95.getCode()); + } else { + pass = new Pass(null); + } + + list.add(pass); + } + + this.listVoltageRate = new ArrayList<>(); + transformData(this.listVoltageRate, listVoltageRate, list, true); + } + + public String judgeNull(Float result) { + return (result == null) ? "/" : result.toString(); + } + + /** + * 谐波电流限值 + * + * @param overLimit + * @return + */ + public List getIHarmList(OverLimitInfoCommDTO overLimit) { + List list = new ArrayList<>(); + list.add(overLimit.getIharm2()); + list.add(overLimit.getIharm3()); + list.add(overLimit.getIharm4()); + list.add(overLimit.getIharm5()); + list.add(overLimit.getIharm6()); + list.add(overLimit.getIharm7()); + list.add(overLimit.getIharm8()); + list.add(overLimit.getIharm9()); + list.add(overLimit.getIharm10()); + list.add(overLimit.getIharm11()); + list.add(overLimit.getIharm12()); + list.add(overLimit.getIharm13()); + list.add(overLimit.getIharm14()); + list.add(overLimit.getIharm15()); + list.add(overLimit.getIharm16()); + list.add(overLimit.getIharm17()); + list.add(overLimit.getIharm18()); + list.add(overLimit.getIharm19()); + list.add(overLimit.getIharm20()); + list.add(overLimit.getIharm21()); + list.add(overLimit.getIharm22()); + list.add(overLimit.getIharm23()); + list.add(overLimit.getIharm24()); + list.add(overLimit.getIharm25()); + return list; + } + + /** + * 谐波电压限值 + * + * @return + */ + public List getVHarmList(OverLimitInfoCommDTO overLimit) { + List list = new ArrayList<>(); + list.add(overLimit.getUharm2()); + list.add(overLimit.getUharm3()); + list.add(overLimit.getUharm4()); + list.add(overLimit.getUharm5()); + list.add(overLimit.getUharm6()); + list.add(overLimit.getUharm7()); + list.add(overLimit.getUharm8()); + list.add(overLimit.getUharm9()); + list.add(overLimit.getUharm10()); + list.add(overLimit.getUharm11()); + list.add(overLimit.getUharm12()); + list.add(overLimit.getUharm13()); + list.add(overLimit.getUharm14()); + list.add(overLimit.getUharm15()); + list.add(overLimit.getUharm16()); + list.add(overLimit.getUharm17()); + list.add(overLimit.getUharm18()); + list.add(overLimit.getUharm19()); + list.add(overLimit.getUharm20()); + list.add(overLimit.getUharm21()); + list.add(overLimit.getUharm22()); + list.add(overLimit.getUharm23()); + list.add(overLimit.getUharm24()); + list.add(overLimit.getUharm25()); + return list; + } + + + /** + * 修复:处理图片字节流+获取自适应宽高(按原图比例,适配Word的EMU单位,防止截断) + * @param multipartFile 上传的图片文件(可为null) + * @param defaultPicResource 默认图片资源(ClassPathResource) + * @return Map 包含content/width/height/type,直接给header用 + */ + private Map handleImageData(MultipartFile multipartFile, ClassPathResource defaultPicResource) { + Map imgMap = new HashMap<>(4); + byte[] imgBytes = null; + String contentType = null; + try { + if (ObjectUtil.isNotEmpty(multipartFile) && multipartFile.getSize() > 0) { + // 处理上传的图片 + imgBytes = multipartFile.getBytes(); + contentType = multipartFile.getContentType(); + } else { + // 处理默认图片,【修复流读取不完整问题】 + if (defaultPicResource != null && defaultPicResource.exists()) { + try (InputStream in = defaultPicResource.getInputStream()) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = in.read(buffer)) != -1) { + baos.write(buffer, 0, len); + } + imgBytes = baos.toByteArray(); + contentType = "image/jpeg"; // 默认图片是jpg + } + } + } + + // 核心修复:获取图片真实宽高 + 按比例自适应缩放(关键!解决只显示一半) + if (imgBytes != null && imgBytes.length > 0) { + ByteArrayInputStream bais = new ByteArrayInputStream(imgBytes); + BufferedImage bufferedImage = ImageIO.read(bais); + int realWidth = bufferedImage.getWidth(); + int realHeight = bufferedImage.getHeight(); + + // 【核心配置】设置Word中图片的最大显示宽度,高度按比例自动计算,永不截断 + int maxWordImgWidth = 550; // 建议值,适配Word页面宽度,可微调 + double scale = 1.0; + if (realWidth > maxWordImgWidth) { + scale = (double) maxWordImgWidth / realWidth; + } + int adaptWidth = (int) (realWidth * scale); + int adaptHeight = (int) (realHeight * scale); + + // 赋值到map,直接给原逻辑的header用 + imgMap.put("content", imgBytes); + imgMap.put("width", adaptWidth); + imgMap.put("height", adaptHeight); + imgMap.put("type", ObjectUtil.isNotEmpty(contentType) ? contentType : "image/jpeg"); + } + } catch (Exception e) { + log.error("处理图片数据异常", e); + } + return imgMap; + } +} diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/RegroupData.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/RegroupDataComm.java similarity index 93% rename from pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/RegroupData.java rename to pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/RegroupDataComm.java index 829a0639e..f264e5136 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/RegroupData.java +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/RegroupDataComm.java @@ -1,10 +1,10 @@ -package com.njcn.harmonic.service.impl; +package com.njcn.harmonic.common.service.impl; import com.njcn.harmonic.pojo.vo.ReportValue; import java.util.List; -public class RegroupData { +public class RegroupDataComm { public static void regroupData(List list, boolean... b) { if (1 == b.length || (2 == b.length && b[1] == false)) { if (0 < list.size()) {