diff --git a/pom.xml b/pom.xml index 776d30ef5..cd720efea 100644 --- a/pom.xml +++ b/pom.xml @@ -53,9 +53,9 @@ nacos - hswbpm + hswbpm - + ${middle.server.url}:8080 diff --git a/pqs-common/common-db/pom.xml b/pqs-common/common-db/pom.xml index 399d07938..5d865cb69 100644 --- a/pqs-common/common-db/pom.xml +++ b/pqs-common/common-db/pom.xml @@ -74,6 +74,12 @@ mybatis-plus-boot-starter + + com.baomidou + dynamic-datasource-spring-boot-starter + 3.5.1 + + diff --git a/pqs-common/common-echarts/src/main/java/com/njcn/echarts/util/BusinessDataUtil.java b/pqs-common/common-echarts/src/main/java/com/njcn/echarts/util/BusinessDataUtil.java index 2a12739c6..d0a3dd132 100644 --- a/pqs-common/common-echarts/src/main/java/com/njcn/echarts/util/BusinessDataUtil.java +++ b/pqs-common/common-echarts/src/main/java/com/njcn/echarts/util/BusinessDataUtil.java @@ -25,7 +25,7 @@ public class BusinessDataUtil { List> unTolerateData = new ArrayList<>(); for (List list : originData) { //是否超过上限 - if (list.get(0) <= 0.03) { + if (list.get(0) <= 0.003) { int line = 230 - 30000 * list.get(0).intValue(); if (list.get(1) > line) { unTolerateData.add(list); diff --git a/pqs-common/common-oss/pom.xml b/pqs-common/common-oss/pom.xml index c31b7a36f..86d8a65be 100644 --- a/pqs-common/common-oss/pom.xml +++ b/pqs-common/common-oss/pom.xml @@ -63,6 +63,13 @@ + + + com.aliyun.oss + aliyun-sdk-oss + 3.18.0 + false + \ No newline at end of file diff --git a/pqs-common/common-redis/src/main/java/com/njcn/redis/pojo/enums/RedisKeyEnum.java b/pqs-common/common-redis/src/main/java/com/njcn/redis/pojo/enums/RedisKeyEnum.java index 9b305da0e..0d16c1eec 100644 --- a/pqs-common/common-redis/src/main/java/com/njcn/redis/pojo/enums/RedisKeyEnum.java +++ b/pqs-common/common-redis/src/main/java/com/njcn/redis/pojo/enums/RedisKeyEnum.java @@ -45,7 +45,22 @@ public enum RedisKeyEnum { /** * 云前置心跳 */ - CLD_HEART_BEAT_KEY("CLD_HEART_BEAT:", 180L); + CLD_HEART_BEAT_KEY("CLD_HEART_BEAT:", 180L), + + /** + * 用户日志队列 + */ + USER_LOG_QUEUE("USER_LOG_QUEUE", -1L), + + /** + * 用户日志邮件推送队列 + */ + USER_LOG_EMAIL_QUEUE("USER_LOG_EMAIL_QUEUE", -1L), + + /** + * 终端日志 + */ + DEVICE_LOG_QUEUE("DEVICE_LOG_QUEUE", -1L); private final String key; diff --git a/pqs-common/common-redis/src/main/java/com/njcn/redis/utils/RedisMessageQueueUtil.java b/pqs-common/common-redis/src/main/java/com/njcn/redis/utils/RedisMessageQueueUtil.java new file mode 100644 index 000000000..5ec6f4454 --- /dev/null +++ b/pqs-common/common-redis/src/main/java/com/njcn/redis/utils/RedisMessageQueueUtil.java @@ -0,0 +1,66 @@ +package com.njcn.redis.utils; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import java.util.concurrent.TimeUnit; + +/** + * Redis 消息队列工具类 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class RedisMessageQueueUtil { + + private final RedisTemplate redisTemplate; + + /** + * 推送消息到队列(左推) + * + * @param queueKey 队列Key + * @param message 消息内容(JSON字符串) + */ + public void pushMessage(String queueKey, String message) { + try { + redisTemplate.opsForList().leftPush(queueKey, message); + } catch (Exception e) { + log.error("推送消息到队列失败,queueKey={}", queueKey, e); + throw e; + } + } + + /** + * 阻塞式弹出消息(右弹) + * + * @param queueKey 队列Key + * @param timeout 超时时间(秒) + * @return 消息内容,超时返回null + */ + public String popMessage(String queueKey, long timeout) { + try { + Object result = redisTemplate.opsForList().rightPop(queueKey, timeout, TimeUnit.SECONDS); + return result != null ? result.toString() : null; + } catch (Exception e) { + log.error("弹出消息失败,queueKey={}", queueKey, e); + return null; + } + } + + /** + * 获取队列长度(用于监控) + * + * @param queueKey 队列Key + * @return 队列长度 + */ + public Long getQueueSize(String queueKey) { + try { + return redisTemplate.opsForList().size(queueKey); + } catch (Exception e) { + log.error("获取队列长度失败,queueKey={}", queueKey, e); + return 0L; + } + } +} \ No newline at end of file diff --git a/pqs-common/common-web/src/main/java/com/njcn/web/config/FeignConfig.java b/pqs-common/common-web/src/main/java/com/njcn/web/config/FeignConfig.java index d8fdfd33e..ec519054b 100644 --- a/pqs-common/common-web/src/main/java/com/njcn/web/config/FeignConfig.java +++ b/pqs-common/common-web/src/main/java/com/njcn/web/config/FeignConfig.java @@ -47,6 +47,7 @@ public class FeignConfig { @Bean public Decoder feignDecoder() { return (response, type) -> { + String bodyStr = Util.toString(response.body().asReader(Util.UTF_8)); //对结果进行转换 HttpResult result = PubUtils.json2obj(bodyStr, type); @@ -60,6 +61,8 @@ public class FeignConfig { } switch (commonResponseEnum) { case SUCCESS: +// case NO_DATA: +// case FAIL: return result; default: throw new BusinessException(result); diff --git a/pqs-common/common-web/src/main/java/com/njcn/web/service/impl/LogServiceImpl.java b/pqs-common/common-web/src/main/java/com/njcn/web/service/impl/LogServiceImpl.java index c1b697e26..f53ce3757 100644 --- a/pqs-common/common-web/src/main/java/com/njcn/web/service/impl/LogServiceImpl.java +++ b/pqs-common/common-web/src/main/java/com/njcn/web/service/impl/LogServiceImpl.java @@ -1,8 +1,6 @@ package com.njcn.web.service.impl; -import com.github.tocrhz.mqtt.publisher.MqttPublisher; import com.njcn.common.config.GeneralInfo; -import com.njcn.common.pojo.annotation.OperateInfo; import com.njcn.common.pojo.constant.LogInfo; import com.njcn.common.pojo.dto.DeviceLogDTO; import com.njcn.common.pojo.dto.LogInfoDTO; @@ -10,6 +8,8 @@ import com.njcn.common.pojo.enums.response.CommonResponseEnum; import com.njcn.common.pojo.response.HttpResult; import com.njcn.common.utils.PubUtils; import com.njcn.common.utils.ReflectCommonUtil; +import com.njcn.redis.pojo.enums.RedisKeyEnum; +import com.njcn.redis.utils.RedisMessageQueueUtil; import com.njcn.web.advice.DeviceLog; import com.njcn.web.service.ILogService; import com.njcn.web.utils.RequestUtil; @@ -46,8 +46,15 @@ public class LogServiceImpl implements ILogService { private final GeneralInfo generalInfo; + /** + * mqtt处理日志异步发布 + */ +// private final MqttPublisher publisher; - private final MqttPublisher publisher; + /** + * redis队列处理日志异步发布 + */ + private final RedisMessageQueueUtil redisMessageQueueUtil; /** @@ -82,14 +89,27 @@ public class LogServiceImpl implements ILogService { String operateType = ReflectCommonUtil.getOperateTypeByMethod(returnType.getMethod()); Integer severity = levelStringToNumber(level); LogInfoDTO logInfoDTO = new LogInfoDTO(loginName, userName, ip, methodDescribe, operateType, result.equalsIgnoreCase("失败") ? 0 : 1, "", severity, type.equalsIgnoreCase("业务事件") ? 0 : 1, generalInfo.getMicroServiceName(), userIndex, LocalDateTime.now()); - publisher.send("/userLog", PubUtils.obj2json(logInfoDTO), 2, false); +// publisher.send("/userLog", PubUtils.obj2json(logInfoDTO), 2, false); + + redisMessageQueueUtil.pushMessage( + RedisKeyEnum.USER_LOG_QUEUE.getKey(), + PubUtils.obj2json(logInfoDTO) + ); + //推送审计消息功能 if (severity != 0) { if (!logInfoDTO.getLoginName().equals(LogInfo.UNKNOWN_USER)) { - publisher.send("/userLogPush", PubUtils.obj2json(logInfoDTO), 2, false); + /**注意,此处是给前端推送的,如果没有了mqtt协议,此处前端就无消息可消费了*/ +// publisher.send("/userLogPush", PubUtils.obj2json(logInfoDTO), 2, false); + //发送邮箱功能 if (severity == 2 && logInfoDTO.getResult() == 0) { //publisher.send("/userLogEmailPush", PubUtils.obj2json(logInfoDTO), 2, false); + +// redisMessageQueueUtil.pushMessage( +// RedisKeyEnum.USER_LOG_EMAIL_QUEUE.getKey(), +// PubUtils.obj2json(logInfoDTO) +// ); } } } @@ -97,8 +117,11 @@ public class LogServiceImpl implements ILogService { if (Objects.nonNull((returnType.getMethod())) && (returnType.getMethod()).isAnnotationPresent(DeviceLog.class)) { String deviceOperate = returnType.getMethod().getAnnotation(DeviceLog.class).operateType(); DeviceLogDTO deviceLogDTO = new DeviceLogDTO(userName, deviceOperate, result.equalsIgnoreCase("失败") ? 0 : 1, "", loginName, userIndex); - publisher.send("/deviceLog", PubUtils.obj2json(deviceLogDTO), 2, false); - +// publisher.send("/deviceLog", PubUtils.obj2json(deviceLogDTO), 2, false); + redisMessageQueueUtil.pushMessage( + RedisKeyEnum.DEVICE_LOG_QUEUE.getKey(), + PubUtils.obj2json(deviceLogDTO) + ); } } @@ -135,7 +158,11 @@ public class LogServiceImpl implements ILogService { String operateType = ReflectCommonUtil.getOperateTypeByMethod(method); Integer severity = levelStringToNumber(level); LogInfoDTO logInfoDTO = new LogInfoDTO(tempLogInfo.getLoginName(), tempLogInfo.getUserName(), tempLogInfo.getIp(), ReflectCommonUtil.getMethodDescribeByMethod(method), operateType, result.equalsIgnoreCase("失败") ? 0 : 1, message, severity, type.equalsIgnoreCase("业务事件") ? 0 : 1, generalInfo.getMicroServiceName(), userIndex, LocalDateTime.now()); - publisher.send("/userLog", PubUtils.obj2json(logInfoDTO), 1, false); +// publisher.send("/userLog", PubUtils.obj2json(logInfoDTO), 1, false); + redisMessageQueueUtil.pushMessage( + RedisKeyEnum.USER_LOG_QUEUE.getKey(), + PubUtils.obj2json(logInfoDTO) + ); auditPush(severity, logInfoDTO); } @@ -163,7 +190,11 @@ public class LogServiceImpl implements ILogService { Integer severity = levelStringToNumber(level); String operateType = ReflectCommonUtil.getOperateTypeByMethod(method); LogInfoDTO logInfoDTO = new LogInfoDTO(loginName, "", ip, ReflectCommonUtil.getMethodDescribeByMethod(method), operateType, result.equalsIgnoreCase("失败") ? 0 : 1, message, severity, type.equalsIgnoreCase("业务事件") ? 0 : 1, generalInfo.getMicroServiceName(), loginName, LocalDateTime.now()); - publisher.send("/userLog", PubUtils.obj2json(logInfoDTO), 1, false); +// publisher.send("/userLog", PubUtils.obj2json(logInfoDTO), 1, false); + redisMessageQueueUtil.pushMessage( + RedisKeyEnum.USER_LOG_QUEUE.getKey(), + PubUtils.obj2json(logInfoDTO) + ); auditPush(severity, logInfoDTO); } @@ -171,7 +202,12 @@ public class LogServiceImpl implements ILogService { //推送审计消息功能 if (severity != 0) { if (!logInfoDTO.getLoginName().equals(LogInfo.UNKNOWN_USER)) { - publisher.send("/userLogPush", PubUtils.obj2json(logInfoDTO), 2, false); + /**注意,此处是给前端推送的,如果没有了mqtt协议,此处前端就无消息可消费了*/ +// publisher.send("/userLogPush", PubUtils.obj2json(logInfoDTO), 2, false); +// redisMessageQueueUtil.pushMessage( +// RedisKeyEnum.USER_LOG_QUEUE.getKey(), +// PubUtils.obj2json(logInfoDTO) +// ); //发送邮箱功能 if (severity == 2 && logInfoDTO.getResult() == 0) { //publisher.send("/userLogEmailPush", PubUtils.obj2json(logInfoDTO), 2, false); diff --git a/pqs-device/common-device-biz/pom.xml b/pqs-device/common-device-biz/pom.xml index ab6181178..339b7e5fa 100644 --- a/pqs-device/common-device-biz/pom.xml +++ b/pqs-device/common-device-biz/pom.xml @@ -60,6 +60,7 @@ pqs-influx ${project.version} + diff --git a/pqs-device/common-device-biz/src/main/java/com/njcn/device/biz/mapper/OverLimitWlMapper.java b/pqs-device/common-device-biz/src/main/java/com/njcn/device/biz/mapper/OverLimitWlMapper.java new file mode 100644 index 000000000..1208e32bd --- /dev/null +++ b/pqs-device/common-device-biz/src/main/java/com/njcn/device/biz/mapper/OverLimitWlMapper.java @@ -0,0 +1,22 @@ +package com.njcn.device.biz.mapper; + + +import com.baomidou.dynamic.datasource.annotation.DS; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.njcn.device.biz.pojo.po.Overlimit; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * Mapper 接口 + *

+ * + * @author xy + * @since 2022-01-04 + */ +@DS("sjzx") +@Mapper +public interface OverLimitWlMapper extends BaseMapper { + + +} 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 @@ - + - \ No newline at end of file + diff --git a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/EventReportService.java b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/EventReportService.java index 96fe0dcd2..017afc76f 100644 --- a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/EventReportService.java +++ b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/EventReportService.java @@ -1,78 +1,78 @@ -package com.njcn.event.service.majornetwork; - -import com.njcn.event.pojo.param.StatisticsParam; -import com.njcn.event.pojo.po.EventDetail; -import com.njcn.event.pojo.vo.*; -import com.njcn.system.pojo.po.DictData; - -import java.text.ParseException; -import java.util.List; - -/** - * <监测点报表> - * - * @author wr - * @createTime: 2023-02-10 - */ -public interface EventReportService { - - /** - *获取Disdip表格(监测点报表专用) - * @param info influxdb查询结果(pqs_eventdetail表) - * @return - */ - List eventDisdip(List info); - - /** - * 获取IEC411数据 - * @param info influxdb查询结果(pqs_eventdetail表) - * @return - */ - List IEC411(List info); - - /** - * 获取IEC28数据 - * @param info influxdb查询结果(pqs_eventdetail表) - * @return - */ - List IEC28(List info); - - /** - *暂降幅值概率分布 - * @param info2 influxdb查询结果(pqs_eventdetail表) - * @return - */ - ProbabilityVO getProbabilityDistribution(List info2); - - /** - * 获取时间列表(月份统计) - * @param info influxdb查询结果(pqs_eventdetail表) - * @return - */ - List getReasonTypeTime(StatisticsParam statisticsParam,List info) throws ParseException; - - /** - * 获取点状表格数据2.1 - * @param info 结果集 - * @param reasonData 暂降原因 - * @param typeData 暂降类型 - * @return - */ - List getPlot(List info, List reasonData, List typeData); - - /** - * 获取详细数据对象 - * @param info - * @param reasonData - * @param typeData - * @return - */ - StatisticVO getStatistic(List info,List reasonData,ListtypeData); - - /** - * 获取密度点图 - * @param info - * @return - */ - Integer[][] getCoords(List info); -} +//package com.njcn.event.service.majornetwork; +// +//import com.njcn.event.pojo.param.StatisticsParam; +//import com.njcn.event.pojo.po.EventDetail; +//import com.njcn.event.pojo.vo.*; +//import com.njcn.system.pojo.po.DictData; +// +//import java.text.ParseException; +//import java.util.List; +// +///** +// * <监测点报表> +// * +// * @author wr +// * @createTime: 2023-02-10 +// */ +//public interface EventReportService { +// +// /** +// *获取Disdip表格(监测点报表专用) +// * @param info influxdb查询结果(pqs_eventdetail表) +// * @return +// */ +// List eventDisdip(List info); +// +// /** +// * 获取IEC411数据 +// * @param info influxdb查询结果(pqs_eventdetail表) +// * @return +// */ +// List IEC411(List info); +// +// /** +// * 获取IEC28数据 +// * @param info influxdb查询结果(pqs_eventdetail表) +// * @return +// */ +// List IEC28(List info); +// +// /** +// *暂降幅值概率分布 +// * @param info2 influxdb查询结果(pqs_eventdetail表) +// * @return +// */ +// ProbabilityVO getProbabilityDistribution(List info2); +// +// /** +// * 获取时间列表(月份统计) +// * @param info influxdb查询结果(pqs_eventdetail表) +// * @return +// */ +// List getReasonTypeTime(StatisticsParam statisticsParam,List info) throws ParseException; +// +// /** +// * 获取点状表格数据2.1 +// * @param info 结果集 +// * @param reasonData 暂降原因 +// * @param typeData 暂降类型 +// * @return +// */ +// List getPlot(List info, List reasonData, List typeData); +// +// /** +// * 获取详细数据对象 +// * @param info +// * @param reasonData +// * @param typeData +// * @return +// */ +// StatisticVO getStatistic(List info,List reasonData,ListtypeData); +// +// /** +// * 获取密度点图 +// * @param info +// * @return +// */ +// Integer[][] getCoords(List info); +//} diff --git a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/AreaAnalysisServiceImpl.java b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/AreaAnalysisServiceImpl.java index f1014d079..e0b9fad7b 100644 --- a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/AreaAnalysisServiceImpl.java +++ b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/AreaAnalysisServiceImpl.java @@ -20,12 +20,11 @@ import com.njcn.event.pojo.vo.AreaAnalysisVO; import com.njcn.event.pojo.vo.VoltageToleranceCurveVO; import com.njcn.event.pojo.vo.VoltageToleranceCurveVO.VoltageToleranceCurveDataList; import com.njcn.event.service.majornetwork.AreaAnalysisService; -import com.njcn.event.service.majornetwork.EventDetailService; +import com.njcn.event.common.service.EventDetailService; import com.njcn.system.api.DicDataFeignClient; import com.njcn.system.enums.DicDataEnum; import com.njcn.system.enums.DicDataTypeEnum; import com.njcn.system.pojo.po.DictData; -import io.swagger.models.auth.In; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -34,8 +33,6 @@ import java.util.function.Function; import java.util.stream.Collectors; - - /** * pqs-event * @@ -54,9 +51,11 @@ public class AreaAnalysisServiceImpl implements AreaAnalysisService { private final EventDetailService eventDetailService; @Override public AreaAnalysisVO getEventReason(DeviceInfoParam.BusinessParam deviceInfoParam) { + //根据单体系统这里只要不为录波的都统计 //获取暂降字典信息 - DictData voltageData = dicDataFeignClient.getDicDataByCode(DicDataEnum.VOLTAGE_DIP.getCode()).getData(); - if(ObjectUtil.isNull(voltageData)){ + DictData recordingWaveData = dicDataFeignClient.getDicDataByCode(DicDataEnum.RECORDING_WAVE.getCode()).getData(); + + if(ObjectUtil.isNull(recordingWaveData)){ throw new BusinessException(DeviceResponseEnum.DIC_GET_EMPTY); } AreaAnalysisVO areaAnalysisVO = new AreaAnalysisVO(); @@ -71,7 +70,7 @@ public class AreaAnalysisServiceImpl implements AreaAnalysisService { List info = eventDetailService.list(new QueryWrapper() .select("advance_reason,advance_type,count(event_id) as count") .in("measurement_point_id", lineIds) - .eq("event_type", voltageData.getId()) + .ne("event_type", recordingWaveData.getId()) .in("advance_reason", dicReasonList.stream().map(DictData::getId).collect(Collectors.toList())) .in("advance_type", dicTypeList.stream().map(DictData::getId).collect(Collectors.toList())) .ge(StrUtil.isNotBlank(deviceInfoParam.getSearchBeginTime()),"start_time" ,DateUtil.beginOfDay(DateUtil.parse(deviceInfoParam.getSearchBeginTime()))) diff --git a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/AreaInfoServiceImpl.java b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/AreaInfoServiceImpl.java index 7dc0b1729..b4eba0e81 100644 --- a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/AreaInfoServiceImpl.java +++ b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/AreaInfoServiceImpl.java @@ -14,7 +14,7 @@ import com.njcn.event.pojo.po.EventDetailNew; import com.njcn.event.pojo.po.RmpEventDetailPO; import com.njcn.event.pojo.vo.AreaSubLineVO; import com.njcn.event.service.majornetwork.AreaInfoService; -import com.njcn.event.service.majornetwork.EventDetailService; +import com.njcn.event.common.service.EventDetailService; import com.njcn.harmonic.api.PollutionSubstationClient; import com.njcn.harmonic.pojo.excel.pollution.UserLinePollution; import lombok.RequiredArgsConstructor; diff --git a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/AreaLineServiceImpl.java b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/AreaLineServiceImpl.java index dfaf08c84..3784187b8 100644 --- a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/AreaLineServiceImpl.java +++ b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/AreaLineServiceImpl.java @@ -24,7 +24,7 @@ import com.njcn.event.pojo.vo.*; import com.njcn.event.pojo.vo.TerminalRunningStatisticsVO.TerminalRunningInfoVO; import com.njcn.event.pojo.vo.TerminalRunningStatisticsVO.TerminalRunningVO; import com.njcn.event.service.majornetwork.AreaLineService; -import com.njcn.event.service.majornetwork.EventDetailService; +import com.njcn.event.common.service.EventDetailService; import com.njcn.event.service.majornetwork.LargeScreenService; import com.njcn.harmonic.pojo.dto.ComAssessDTO; import com.njcn.harmonic.pojo.po.PQSComAssesPO; @@ -47,6 +47,7 @@ import java.util.*; import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.Stream; import static com.njcn.event.influxdb.QueryBuilder.beginOfDay; import static com.njcn.event.influxdb.QueryBuilder.endOfDay; @@ -122,9 +123,12 @@ public class AreaLineServiceImpl implements AreaLineService { @Override public EventHeatMapVO getEventHeatMap(DeviceInfoParam.BusinessParam deviceInfoParam) { + //新增需求添加中断 //获取暂降字典信息 DictData voltageData = dicDataFeignClient.getDicDataByCode(DicDataEnum.VOLTAGE_DIP.getCode()).getData(); - if(ObjectUtil.isNull(voltageData)){ + DictData shortInterruptionsData = dicDataFeignClient.getDicDataByCode(DicDataEnum.SHORT_INTERRUPTIONS.getCode()).getData(); + + if(ObjectUtil.isNull(voltageData)||ObjectUtil.isNull(shortInterruptionsData)){ throw new BusinessException(DeviceResponseEnum.DIC_GET_EMPTY); } EventHeatMapVO eventHeatMapVO = new EventHeatMapVO(); @@ -146,7 +150,7 @@ public class AreaLineServiceImpl implements AreaLineService { List info = eventDetailService.list(new QueryWrapper() .select("measurement_point_id as measurementPointId,count(file_flag) as fileFlag") .in("measurement_point_id", lineIndexs) - .eq("event_type", voltageData.getId()) + .in("event_type", Stream.of(voltageData.getId(),shortInterruptionsData.getId()).collect(Collectors.toList())) .ge("start_time" ,DateUtil.beginOfDay(DateUtil.parse(deviceInfoParam.getSearchBeginTime()))) .le("start_time", DateUtil.endOfDay(DateUtil.parse(deviceInfoParam.getSearchEndTime()))) .groupBy("measurement_point_id") diff --git a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/AreaStatisticalServiceImpl.java b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/AreaStatisticalServiceImpl.java index b71c1e555..faf6703ce 100644 --- a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/AreaStatisticalServiceImpl.java +++ b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/AreaStatisticalServiceImpl.java @@ -22,7 +22,7 @@ import com.njcn.event.pojo.vo.AreaStatisticalVO.VoltageStatisticsVO; import com.njcn.event.pojo.vo.MonthCalculationVO; import com.njcn.event.pojo.vo.VoltageLevelCalculationVO; import com.njcn.event.service.majornetwork.AreaStatisticalService; -import com.njcn.event.service.majornetwork.EventDetailService; +import com.njcn.event.common.service.EventDetailService; import com.njcn.event.pojo.vo.NodeVO; import com.njcn.system.api.DicDataFeignClient; import com.njcn.system.enums.DicDataEnum; diff --git a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/EventDistributionStatisticsServiceImpl.java b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/EventDistributionStatisticsServiceImpl.java index 537be7ec9..6970fcf76 100644 --- a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/EventDistributionStatisticsServiceImpl.java +++ b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/EventDistributionStatisticsServiceImpl.java @@ -8,7 +8,7 @@ import com.njcn.common.pojo.param.StatisticsBizBaseParam; import com.njcn.device.pms.api.PmsGeneralDeviceInfoClient; import com.njcn.device.pms.pojo.dto.PmsGeneralDeviceDTO; import com.njcn.device.pms.pojo.param.PmsDeviceInfoParam; -import com.njcn.event.mapper.majornetwork.EventDistributionStatisticsMapper; +import com.njcn.event.common.mapper.EventDistributionStatisticsMapper; import com.njcn.event.pojo.po.EventDistributionStatisticsPO; import com.njcn.event.pojo.po.EventDurationLineChartPO; import com.njcn.event.pojo.po.EventFeatureAmplitudeLineChartPO; @@ -21,8 +21,6 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collections; import java.util.List; diff --git a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/ReportServiceImpl.java b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/ReportServiceImpl.java index 0908174af..2bf06c9ce 100644 --- a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/ReportServiceImpl.java +++ b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/ReportServiceImpl.java @@ -35,6 +35,7 @@ import com.njcn.device.pq.pojo.vo.AreaLineInfoVO; import com.njcn.device.pq.pojo.vo.LineDetailDataVO; import com.njcn.echarts.pojo.constant.PicCommonData; import com.njcn.echarts.util.DrawPicUtil; +import com.njcn.event.common.service.EventReportService; import com.njcn.event.enums.EventResponseEnum; import com.njcn.event.mapper.majornetwork.EventDetailMapper; import com.njcn.event.mapper.majornetwork.ReportMapper; @@ -44,11 +45,10 @@ import com.njcn.event.pojo.po.EventDetailNew; import com.njcn.event.pojo.po.Eventass; import com.njcn.event.pojo.po.RmpEventDetailPO; import com.njcn.event.pojo.vo.*; -import com.njcn.event.service.majornetwork.EventAnalysisService; -import com.njcn.event.service.majornetwork.EventDetailService; -import com.njcn.event.service.majornetwork.EventReportService; +import com.njcn.event.common.service.EventAnalysisService; +import com.njcn.event.common.service.EventDetailService; import com.njcn.event.service.majornetwork.ReportService; -import com.njcn.event.utils.WordUtils; +import com.njcn.event.common.utils.WordUtils; import com.njcn.oss.constant.OssPath; import com.njcn.oss.utils.FileStorageUtil; import com.njcn.poi.util.PoiUtil; @@ -89,10 +89,8 @@ import org.apache.poi.ss.usermodel.VerticalAlignment; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.util.Units; import org.apache.poi.xwpf.usermodel.*; -import org.jetbrains.annotations.NotNull; import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; import org.springframework.beans.BeanUtils; -import org.springframework.core.io.InputStreamResource; import org.springframework.stereotype.Service; import sun.misc.BASE64Decoder; @@ -4271,11 +4269,11 @@ public class ReportServiceImpl implements ReportService { List obs = new ArrayList<>(); ArrayList> list = new ArrayList<>(); for (EventDetailNew eventDetail : detailList) { - obs.add(new OB(Double.parseDouble(eventDetail.getDuration() / 1000 + "") + obs.add(new OB(Double.parseDouble(eventDetail.getDuration() + "") , Double.parseDouble(eventDetail.getFeatureAmplitude() * 100 + ""))); ArrayList doubles = new ArrayList<>(); - doubles.add(Double.parseDouble(eventDetail.getDuration() / 1000 + "")); + doubles.add(Double.parseDouble(eventDetail.getDuration() + "")); doubles.add(Double.parseDouble(String.valueOf(eventDetail.getFeatureAmplitude() * 100))); list.add(doubles); } @@ -4332,10 +4330,10 @@ public class ReportServiceImpl implements ReportService { ArrayList> list = new ArrayList<>(); for (EventDetailNew eventDetail : detailList) { - obs.add(new OB(Double.parseDouble(eventDetail.getDuration() / 1000 + ""), Double.parseDouble(eventDetail.getFeatureAmplitude() * 100 + ""))); + obs.add(new OB(Double.parseDouble(eventDetail.getDuration() + ""), Double.parseDouble(eventDetail.getFeatureAmplitude() * 100 + ""))); ArrayList doubles = new ArrayList<>(); - doubles.add(Double.parseDouble(eventDetail.getDuration() / 1000 + "")); + doubles.add(Double.parseDouble(eventDetail.getDuration() + "")); doubles.add(Double.parseDouble(String.valueOf(eventDetail.getFeatureAmplitude() * 100))); list.add(doubles); } @@ -7203,11 +7201,11 @@ public class ReportServiceImpl implements ReportService { List obs = new ArrayList<>(); ArrayList> list = new ArrayList<>(); for (EventDetailNew eventDetail : detailList) { - obs.add(new OB(Double.parseDouble(eventDetail.getDuration() / 1000 + "") + obs.add(new OB(Double.parseDouble(eventDetail.getDuration() + "") , Double.parseDouble(eventDetail.getFeatureAmplitude() * 100 + ""))); ArrayList doubles = new ArrayList<>(); - doubles.add(Double.parseDouble(eventDetail.getDuration() / 1000 + "")); + doubles.add(Double.parseDouble(eventDetail.getDuration() + "")); doubles.add(Double.parseDouble(String.valueOf(eventDetail.getFeatureAmplitude() * 100))); list.add(doubles); } @@ -7264,10 +7262,10 @@ public class ReportServiceImpl implements ReportService { ArrayList> list = new ArrayList<>(); for (EventDetailNew eventDetail : detailList) { - obs.add(new OB(Double.parseDouble(eventDetail.getDuration() / 1000 + ""), Double.parseDouble(eventDetail.getFeatureAmplitude() * 100 + ""))); + obs.add(new OB(Double.parseDouble(eventDetail.getDuration() + ""), Double.parseDouble(eventDetail.getFeatureAmplitude() * 100 + ""))); ArrayList doubles = new ArrayList<>(); - doubles.add(Double.parseDouble(eventDetail.getDuration() / 1000 + "")); + doubles.add(Double.parseDouble(eventDetail.getDuration() + "")); doubles.add(Double.parseDouble(String.valueOf(eventDetail.getFeatureAmplitude() * 100))); list.add(doubles); } @@ -7991,7 +7989,7 @@ public class ReportServiceImpl implements ReportService { } for (int i = 0; i < areaTableParam.getInfo().size(); i++) { Double eventvalue = areaTableParam.getInfo().get(i).getFeatureAmplitude(); - double persisttime = areaTableParam.getInfo().get(i).getDuration(); + double persisttime = areaTableParam.getInfo().get(i).getDuration()*1000; if (eventvalue * 100 < 1 && eventvalue * 100 >= 0) { if (persisttime > 10 && persisttime <= 100) { arr[16][0]++; @@ -8719,28 +8717,28 @@ public class ReportServiceImpl implements ReportService { List sisttime = new ArrayList<>(); for (EventDetailNew eventDetail : info) { Double persistTime = eventDetail.getDuration(); - if (persistTime / 1000 < 0.1) { + if (persistTime < 0.1) { timeMap2.put("<0.1", timeMap2.get("<0.1") + 1); } - if (persistTime / 1000 < 0.25) { + if (persistTime < 0.25) { timeMap2.put("<0.25", timeMap2.get("<0.25") + 1); } - if (persistTime / 1000 < 0.5) { + if (persistTime < 0.5) { timeMap2.put("<0.5", timeMap2.get("<0.5") + 1); } - if (persistTime / 1000 < 1) { + if (persistTime < 1) { timeMap2.put("<1", timeMap2.get("<1") + 1); } - if (persistTime / 1000 < 3) { + if (persistTime < 3) { timeMap2.put("<3", timeMap2.get("<3") + 1); } - if (persistTime / 1000 < 20) { + if (persistTime < 20) { timeMap2.put("<20", timeMap2.get("<20") + 1); } - if (persistTime / 1000 < 60) { + if (persistTime < 60) { timeMap2.put("<60", timeMap2.get("<60") + 1); } - if (persistTime / 1000 < 180) { + if (persistTime < 180) { timeMap2.put("<180", timeMap2.get("<180") + 1); } } @@ -8807,7 +8805,7 @@ public class ReportServiceImpl implements ReportService { for (int i = 0; i < xbardata.size(); i++) { OB ob = xbardata.get(i); //是否超过上限 - if (ob.getA() <= 0.03) { + if (ob.getA() <= 0.003) { int line = 230 - 30000 * (int) ob.getA(); if (ob.getB() > line) { pointno[i][0] = ob.getA(); diff --git a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/RmpEventDetailServiceImpl.java b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/RmpEventDetailServiceImpl.java index 1e5239a07..7c349a1d7 100644 --- a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/RmpEventDetailServiceImpl.java +++ b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/RmpEventDetailServiceImpl.java @@ -36,7 +36,7 @@ import com.njcn.device.pq.pojo.vo.GridDiagramVO; import com.njcn.device.pq.pojo.vo.LineDetailVO; import com.njcn.event.enums.EventResponseEnum; import com.njcn.event.mapper.majornetwork.RMpEventDetailMMapper; -import com.njcn.event.mapper.majornetwork.RmpEventDetailMapper; +import com.njcn.event.common.mapper.RmpEventDetailMapper; import com.njcn.event.pojo.dto.EventCount; import com.njcn.event.pojo.param.EventBaseParam; import com.njcn.event.pojo.param.UniversalFrontEndParam; diff --git a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/TransientServiceImpl.java b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/TransientServiceImpl.java index 623fc9a66..b770d9e50 100644 --- a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/TransientServiceImpl.java +++ b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/TransientServiceImpl.java @@ -25,7 +25,7 @@ import com.njcn.event.file.component.WaveFileComponent; import com.njcn.event.file.pojo.dto.WaveDataDTO; import com.njcn.event.file.pojo.enums.WaveFileResponseEnum; import com.njcn.event.mapper.distribution.PwRmpEventDetailMapper; -import com.njcn.event.mapper.majornetwork.RmpEventDetailMapper; +import com.njcn.event.common.mapper.RmpEventDetailMapper; import com.njcn.event.mapper.majornetwork.TransientMapper; import com.njcn.event.pojo.param.EventVerifyReasonParam; import com.njcn.event.pojo.param.TransientParam; @@ -33,7 +33,7 @@ import com.njcn.event.pojo.po.EventDetail; import com.njcn.event.pojo.po.EventDetailNew; import com.njcn.event.pojo.po.RmpEventDetailPO; import com.njcn.event.pojo.vo.TransientVO; -import com.njcn.event.service.majornetwork.EventDetailService; +import com.njcn.event.common.service.EventDetailService; import com.njcn.event.service.majornetwork.TransientService; import com.njcn.minioss.config.MinIossProperties; import com.njcn.minioss.util.MinIoUtils; @@ -56,7 +56,6 @@ import java.text.DecimalFormat; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; diff --git a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/VoltageRideThroughEventServiceImpl.java b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/VoltageRideThroughEventServiceImpl.java index bf8bb409e..64ebc6b8d 100644 --- a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/VoltageRideThroughEventServiceImpl.java +++ b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/VoltageRideThroughEventServiceImpl.java @@ -10,7 +10,7 @@ import com.njcn.event.pojo.param.VoltageRideThroughQueryParam; import com.njcn.event.pojo.po.EventDetail; import com.njcn.event.pojo.vo.EventNewStationVo; import com.njcn.event.pojo.vo.VoltageRideThroughVo; -import com.njcn.event.service.majornetwork.EventDetailService; +import com.njcn.event.common.service.EventDetailService; import com.njcn.event.service.majornetwork.SpThroughService; import com.njcn.event.service.majornetwork.VoltageRideThroughEventService; import com.njcn.event.pojo.param.SpThroughParam; diff --git a/pqs-event/event-common/pom.xml b/pqs-event/event-common/pom.xml new file mode 100644 index 000000000..c400005d2 --- /dev/null +++ b/pqs-event/event-common/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + + com.njcn + pqs-event + 1.0.0 + + + + event-common + 1.0.0 + event-common + event-common + + + + + 8 + 8 + UTF-8 + + + + + + com.njcn + event-api + 1.0.0 + + + com.njcn + advance-api + 1.0.0 + compile + + + + + + + diff --git a/pqs-event/event-boot/src/main/java/com/njcn/event/mapper/majornetwork/EventDistributionStatisticsMapper.java b/pqs-event/event-common/src/main/java/com/njcn/event/common/mapper/EventDistributionStatisticsMapper.java similarity index 98% rename from pqs-event/event-boot/src/main/java/com/njcn/event/mapper/majornetwork/EventDistributionStatisticsMapper.java rename to pqs-event/event-common/src/main/java/com/njcn/event/common/mapper/EventDistributionStatisticsMapper.java index fdf9405ae..e5d4aefd0 100644 --- a/pqs-event/event-boot/src/main/java/com/njcn/event/mapper/majornetwork/EventDistributionStatisticsMapper.java +++ b/pqs-event/event-common/src/main/java/com/njcn/event/common/mapper/EventDistributionStatisticsMapper.java @@ -1,4 +1,4 @@ -package com.njcn.event.mapper.majornetwork; +package com.njcn.event.common.mapper; import com.njcn.event.pojo.po.EventDistributionStatisticsPO; import com.njcn.event.pojo.po.EventDurationLineChartPO; diff --git a/pqs-event/event-boot/src/main/java/com/njcn/event/mapper/majornetwork/RmpEventDetailMapper.java b/pqs-event/event-common/src/main/java/com/njcn/event/common/mapper/RmpEventDetailMapper.java similarity index 97% rename from pqs-event/event-boot/src/main/java/com/njcn/event/mapper/majornetwork/RmpEventDetailMapper.java rename to pqs-event/event-common/src/main/java/com/njcn/event/common/mapper/RmpEventDetailMapper.java index 63be2edf0..1fdce8565 100644 --- a/pqs-event/event-boot/src/main/java/com/njcn/event/mapper/majornetwork/RmpEventDetailMapper.java +++ b/pqs-event/event-common/src/main/java/com/njcn/event/common/mapper/RmpEventDetailMapper.java @@ -1,4 +1,4 @@ -package com.njcn.event.mapper.majornetwork; +package com.njcn.event.common.mapper; import cn.hutool.core.date.DateTime; import com.baomidou.mybatisplus.core.mapper.BaseMapper; diff --git a/pqs-event/event-boot/src/main/java/com/njcn/event/mapper/majornetwork/mapping/RmpEventDetailMapper.xml b/pqs-event/event-common/src/main/java/com/njcn/event/common/mapper/mapping/RmpEventDetailMapper.xml similarity index 97% rename from pqs-event/event-boot/src/main/java/com/njcn/event/mapper/majornetwork/mapping/RmpEventDetailMapper.xml rename to pqs-event/event-common/src/main/java/com/njcn/event/common/mapper/mapping/RmpEventDetailMapper.xml index eec9701f6..d914cee92 100644 --- a/pqs-event/event-boot/src/main/java/com/njcn/event/mapper/majornetwork/mapping/RmpEventDetailMapper.xml +++ b/pqs-event/event-common/src/main/java/com/njcn/event/common/mapper/mapping/RmpEventDetailMapper.xml @@ -1,5 +1,5 @@ - + 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 99% 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 index 151bb7168..8ca6c5648 100644 --- 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 @@ -1,6 +1,6 @@ - + + - SELECT a.id, a.NAME, @@ -40,7 +40,7 @@ a.state = 1 - SELECT DISTINCT a.id, @@ -53,10 +53,6 @@ LEFT JOIN sys_dept_temp b ON a.Id = b.temp_id WHERE a.activation = 1 - and b.dept_id in - - #{item} - order by a.sort asc 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/HarmLineDetailDataCommDTO.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/pojo/dto/HarmLineDetailDataCommDTO.java new file mode 100644 index 000000000..811421d9d --- /dev/null +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/pojo/dto/HarmLineDetailDataCommDTO.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 HarmLineDetailDataCommDTO { + + 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..f6480bbc0 --- /dev/null +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/CustomReportTableService.java @@ -0,0 +1,27 @@ +package com.njcn.harmonic.common.service; + +import com.njcn.harmonic.common.pojo.dto.DeviceUnitCommDTO; +import com.njcn.harmonic.pojo.param.ReportSearchParam; + +import javax.servlet.http.HttpServletResponse; +import java.util.Map; + +/** + * pqs + * + * @author cdf + * @date 2026/1/15 + */ +public interface CustomReportTableService { + + + /** + * 替换报表数据并返回 + * + * @param reportSearchParam 请求参数 + * @param response + * @author qijian + * @date 2022/10/18 + */ + void getCustomReport(ReportSearchParam reportSearchParam, Map newMap, DeviceUnitCommDTO deviceUnitCommDTO, 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..64853e817 --- /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.HarmLineDetailDataCommDTO; +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, + HarmLineDetailDataCommDTO 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..45976e1f3 --- /dev/null +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/CustomReportTableServiceImpl.java @@ -0,0 +1,778 @@ +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.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; +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.common.pojo.dto.DeviceUnitCommDTO; +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,Map newMap,DeviceUnitCommDTO deviceUnitCommDTO, 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, newMap,deviceUnitCommDTO,response); + + log.info("报表执行时间{}秒", timeInterval.intervalSecond()); + } + } + + + /** + * 处理 + * + * @author cdf + * @date 2023/10/8 + */ + + private void analyzeReport(ReportSearchParam reportSearchParam, ExcelRptTemp excelRptTemp,Map newMap,DeviceUnitCommDTO deviceUnitCommDTO, 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(() -> { + DynamicDataSourceContextHolder.push("sjzx"); + //avg.max,min,cp95 + try { + 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); + } + + }); + }); + }finally { + DynamicDataSourceContextHolder.poll(); + } + })); + }); + + // 等待所有任务完成 + for (Future future : futures) { + try { + future.get(); // 这会阻塞直到任务完成或抛出异常 + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + log.error("自定义报表多线程查询流程出错!错误信息{}",e.getMessage()); + } + } + + //处理指标最终判定合格还是不合格 + dealTargetResult(assNoPassMap, limitTargetMapX, endList); + } + resultAssemble(endList,reportSearchParam,newMap,deviceUnitCommDTO,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); + } + + + /** + * 数据单位信息 + */ + private Map unitMap(DeviceUnitCommDTO deviceUnit) { + 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,Map finalTerminalMap,DeviceUnitCommDTO deviceUnitCommDTO,JSONArray jsonArray){ + if (CollUtil.isNotEmpty(endList)) { + //数据单位信息 + Map unit = unitMap(deviceUnitCommDTO); + //进行反向赋值到模板 + //1、根据itemName分组 + Map> assMap = endList.stream().collect(Collectors.groupingBy(ReportTemplateDTO::getItemName)); + //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 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..c01f30c63 --- /dev/null +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/MonitorCommReportServiceImpl.java @@ -0,0 +1,690 @@ +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..74d99249a --- /dev/null +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/MonitorHarmonicReportServiceImpl.java @@ -0,0 +1,1853 @@ +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.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.HarmLineDetailDataCommDTO; +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, + HarmLineDetailDataCommDTO 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 = ""; + + // 获取电压偏差 + // 值错误判断 + 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())); + } + } + 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)&&"".equals(strResultVdeviationdataValue)) { + 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()) { diff --git a/pqs-system/system-boot/src/main/java/com/njcn/system/consumer/RedisLogConsumer.java b/pqs-system/system-boot/src/main/java/com/njcn/system/consumer/RedisLogConsumer.java new file mode 100644 index 000000000..331803512 --- /dev/null +++ b/pqs-system/system-boot/src/main/java/com/njcn/system/consumer/RedisLogConsumer.java @@ -0,0 +1,371 @@ +package com.njcn.system.consumer; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; +import com.njcn.common.pojo.constant.LogInfo; +import com.njcn.common.pojo.constant.PatternRegex; +import com.njcn.common.pojo.dto.LogInfoDTO; +import com.njcn.common.utils.PubUtils; +import com.njcn.redis.pojo.enums.RedisKeyEnum; +import com.njcn.redis.utils.RedisMessageQueueUtil; +import com.njcn.redis.utils.RedisUtil; +import com.njcn.system.service.IUserLogService; +import com.njcn.user.api.UserFeignClient; +import com.njcn.user.pojo.po.User; +import com.njcn.web.utils.EmailUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * Redis 日志消费者 + * 替代原 MQTT 订阅方式,从 Redis List 中消费日志消息 + * + * 核心优化: + * 1. 多线程并发消费(3个用户日志线程 + 1个邮件线程) + * 2. 智能批量入库(满50条或超时2秒自动刷新) + * 3. 实时性保证(BRPOP阻塞式消费,延迟<2秒) + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class RedisLogConsumer { + + private final RedisMessageQueueUtil redisMessageQueueUtil; + private final IUserLogService userLogService; + private final UserFeignClient userFeignClient; + private final RedisUtil redisUtil; + private final EmailUtil emailUtil; + + private ExecutorService executorService; + private volatile boolean running = true; + + /** + * 用户角色类型缓存(用于判断日志类型) + */ + private JSONObject userRoleTypeCache = null; + + /** + * 批量阈值:每批最多50条 + */ + private static final int BATCH_SIZE = 50; + + /** + * 超时阈值:2秒未满50条也强制刷新 + */ + private static final long FLUSH_TIMEOUT_MS = 2000; + + @PostConstruct + public void startConsume() { + log.info("启动 Redis 日志消费者..."); + + // 创建消费线程(3个用户日志 + 1个邮件推送 + 1个设备日志,根据需要调整) + executorService = Executors.newFixedThreadPool(5, r -> { + Thread thread = new Thread(r); + thread.setDaemon(false); // 非守护线程,确保消息消费完 + return thread; + }); + + // 启动3个用户日志消费线程 + for (int i = 0; i < 3; i++) { + final int threadId = i; + executorService.submit(() -> consumeUserLogWithBatch(threadId)); + } + + // 启动1个邮件推送消费线程 + executorService.submit(this::consumeEmailPush); + + // 启动1个设备日志消费线程(可选) + // executorService.submit(this::consumeDeviceLog); + + log.info("Redis 日志消费者启动完成(3个用户日志线程 + 1个邮件线程)"); + } + + /** + * 消费用户日志(带批量优化) + */ + private void consumeUserLogWithBatch(int threadId) { + log.info("用户日志消费线程-{} 启动", threadId); + + List buffer = new ArrayList<>(BATCH_SIZE); + long lastFlushTime = System.currentTimeMillis(); + + while (running) { + try { + // BRPOP 阻塞1秒(缩短超时时间,用于定期检查批量刷新条件) + String logJson = redisMessageQueueUtil.popMessage( + RedisKeyEnum.USER_LOG_QUEUE.getKey(), + 1 + ); + + // 收集到消息,加入缓冲区 + if (logJson != null) { + buffer.add(logJson); + } + + // 批量刷新条件:满50条 OR 距离上次刷新超过2秒 + boolean shouldFlush = buffer.size() >= BATCH_SIZE || + (System.currentTimeMillis() - lastFlushTime > FLUSH_TIMEOUT_MS && !buffer.isEmpty()); + + if (shouldFlush) { + batchProcessUserLogs(buffer, threadId); + buffer.clear(); + lastFlushTime = System.currentTimeMillis(); + } + + } catch (Exception e) { + log.error("线程-{} 消费用户日志失败", threadId, e); + try { + Thread.sleep(1000); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + break; + } + } + } + + // 线程退出前,刷新剩余缓冲区 + if (!buffer.isEmpty()) { + batchProcessUserLogs(buffer, threadId); + } + + log.info("用户日志消费线程-{} 退出", threadId); + } + + /** + * 批量处理用户日志 + */ + private void batchProcessUserLogs(List logJsonList, int threadId) { + if (logJsonList.isEmpty()) { + return; + } + + try { + // 确保用户角色类型缓存已加载 + loadUserRoleTypeCache(); + + // 批量解析并处理 + for (String logJson : logJsonList) { + try { + LogInfoDTO logInfoDTO = PubUtils.json2obj(logJson, LogInfoDTO.class); + // 过滤无效日志 + if (logInfoDTO.getLoginName().equals(LogInfo.UNKNOWN_USER) + || logInfoDTO.getOperate().equals(LogInfo.UNKNOWN_OPERATE) + || logInfoDTO.getIp().equals(LogInfo.UNKNOWN_IP)) { + continue; + } + // 设置日志类型(业务事件=0,系统事件=1) + if ("注销".equals(logInfoDTO.getOperateType()) || "认证".equals(logInfoDTO.getOperateType())) { + logInfoDTO.setType(1); // 系统事件 + } else { + String loginName = logInfoDTO.getLoginName(); + if (StrUtil.isNotBlank(loginName) && userRoleTypeCache.containsKey(loginName)) { + if ((Integer) userRoleTypeCache.get(loginName) == 2) { + logInfoDTO.setType(0); // 业务事件 + } else { + logInfoDTO.setType(1); // 系统事件 + } + } else { + logInfoDTO.setType(1); // 默认系统事件 + } + } + // 入库 + userLogService.addUserLog(logInfoDTO); + } catch (Exception e) { + log.error("解析日志失败: {}", logJson, e); + } + } + + log.info("线程-{} 批量入库 {} 条日志", threadId, logJsonList.size()); + + } catch (Exception e) { + log.error("线程-{} 批量处理日志失败,涉及 {} 条", threadId, logJsonList.size(), e); + } + } + + /** + * 加载用户角色类型缓存 + */ + private void loadUserRoleTypeCache() { + if (Objects.isNull(userRoleTypeCache)) { + userRoleTypeCache = (JSONObject) redisUtil.getObjectByKey(RedisKeyEnum.USER_ROLE_TYPE_KEY.getKey()); + if (Objects.isNull(userRoleTypeCache)) { + // 调用 Feign 接口获取用户角色列表(会自动写入 Redis) + userFeignClient.userRoleList(); + userRoleTypeCache = (JSONObject) redisUtil.getObjectByKey(RedisKeyEnum.USER_ROLE_TYPE_KEY.getKey()); + } + } + } + + /** + * 降级处理:批量失败时逐条处理(已移除,直接在批量方法中逐条调用) + */ + private void fallbackProcessOneByOne(List logJsonList, int threadId) { + log.warn("线程-{} 批量入库失败,降级为逐条处理", threadId); + + // 确保用户角色类型缓存已加载 + loadUserRoleTypeCache(); + + for (String logJson : logJsonList) { + try { + LogInfoDTO logInfoDTO = PubUtils.json2obj(logJson, LogInfoDTO.class); + + // 过滤无效日志 + if (logInfoDTO.getLoginName().equals(LogInfo.UNKNOWN_USER) + || logInfoDTO.getOperate().equals(LogInfo.UNKNOWN_OPERATE) + || logInfoDTO.getIp().equals(LogInfo.UNKNOWN_IP)) { + continue; + } + + // 设置日志类型 + if ("注销".equals(logInfoDTO.getOperateType()) || "认证".equals(logInfoDTO.getOperateType())) { + logInfoDTO.setType(1); + } else { + String loginName = logInfoDTO.getLoginName(); + if (StrUtil.isNotBlank(loginName) && userRoleTypeCache.containsKey(loginName)) { + if ((Integer) userRoleTypeCache.get(loginName) == 2) { + logInfoDTO.setType(0); + } else { + logInfoDTO.setType(1); + } + } else { + logInfoDTO.setType(1); + } + } + + userLogService.addUserLog(logInfoDTO); + + } catch (Exception e) { + log.error("线程-{} 单条处理也失败: {}", threadId, logJson, e); + } + } + } + + /** + * 消费邮件推送(无需批量优化,邮件量少) + */ + private void consumeEmailPush() { + log.info("邮件推送消费线程启动"); + + while (running) { + try { + String pushJson = redisMessageQueueUtil.popMessage( + RedisKeyEnum.USER_LOG_EMAIL_QUEUE.getKey(), + 3 // 邮件推送不频繁,5秒超时即可 + ); + if (pushJson != null) { + log.debug("消费邮件推送: {}", pushJson); + // 解析日志DTO + LogInfoDTO auditLogVO = PubUtils.json2obj(pushJson, LogInfoDTO.class); + // 获取审计管理员的邮箱列表 + List data = userFeignClient.getUserListByRoleCode("audit_manager").getData(); + List emails = data.stream() + .filter(x -> Pattern.matches(PatternRegex.EMAIL_REGEX, x.getEmail())) + .filter(x -> StrUtil.isNotBlank(x.getEmail()) && x.getEmailNotice() == 1) + .map(User::getEmail) + .collect(Collectors.toList()); + // 发送邮件 + if (CollUtil.isNotEmpty(emails)) { + StringBuilder describe = new StringBuilder(); + describe.append(auditLogVO.getType() == 0 ? "业务事件 -> " : "系统事件 -> "); + describe.append(auditLogVO.getUserName()).append("在") + .append(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(auditLogVO.getCreateTime())) + .append("在") + .append(auditLogVO.getIp()) + .append("执行了") + .append(auditLogVO.getOperate()) + .append(",结果为"); + if (auditLogVO.getResult() == 1) { + describe.append("成功"); + } + if (auditLogVO.getResult() == 0) { + describe.append("失败").append(",失败原因为").append(auditLogVO.getFailReason()); + } + emailUtil.sendMultiple(emails, "告警消息", describe.toString(), false); + } + } + + } catch (Exception e) { + log.error("消费邮件推送失败", e); + try { + Thread.sleep(1000); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + break; + } + } + } + + log.info("邮件推送消费线程退出"); + } + + /** + * 消费设备日志(可选,如果需要处理设备日志) + */ + private void consumeDeviceLog() { + log.info("设备日志消费线程启动"); + + while (running) { + try { + String deviceLogJson = redisMessageQueueUtil.popMessage( + RedisKeyEnum.DEVICE_LOG_QUEUE.getKey(), + 5 // 设备日志不频繁,5秒超时即可 + ); + + if (deviceLogJson != null) { + log.debug("消费设备日志: {}", deviceLogJson); + // TODO: 解析并保存设备日志 + // DeviceLog deviceLog = JSONUtil.toBean(deviceLogJson, DeviceLog.class); + // deviceLogService.save(deviceLog); + } + + } catch (Exception e) { + log.error("消费设备日志失败", e); + try { + Thread.sleep(1000); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + break; + } + } + } + + log.info("设备日志消费线程退出"); + } + + @PreDestroy + public void shutdown() { + log.info("开始停止 Redis 日志消费者..."); + running = false; + + if (executorService != null) { + executorService.shutdown(); + try { + // 等待60秒,让队列中的消息处理完 + if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) { + log.warn("消费线程未在60秒内完成,强制关闭"); + executorService.shutdownNow(); + } + } catch (InterruptedException e) { + log.error("等待消费线程关闭被中断", e); + executorService.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + + log.info("Redis 日志消费者已停止"); + } +} \ No newline at end of file diff --git a/pqs-system/system-boot/src/main/java/com/njcn/system/handler/MqttMessageHandler.java b/pqs-system/system-boot/src/main/java/com/njcn/system/handler/MqttMessageHandler.java index f59663ea2..9c28ef7a5 100644 --- a/pqs-system/system-boot/src/main/java/com/njcn/system/handler/MqttMessageHandler.java +++ b/pqs-system/system-boot/src/main/java/com/njcn/system/handler/MqttMessageHandler.java @@ -1,10 +1,8 @@ package com.njcn.system.handler; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; -import com.github.tocrhz.mqtt.annotation.MqttSubscribe; import com.github.tocrhz.mqtt.annotation.Payload; import com.njcn.common.pojo.constant.LogInfo; import com.njcn.common.pojo.constant.PatternRegex; @@ -16,17 +14,14 @@ import com.njcn.system.service.IUserLogService; import com.njcn.user.api.UserFeignClient; import com.njcn.user.pojo.po.User; import com.njcn.web.utils.EmailUtil; -import io.swagger.models.auth.In; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.paho.client.mqttv3.MqttMessage; -import org.springframework.data.redis.core.BoundHashOperations; import org.springframework.stereotype.Component; import java.nio.charset.StandardCharsets; import java.time.format.DateTimeFormatter; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -49,11 +44,12 @@ public class MqttMessageHandler { + private JSONObject jsonObject = null; /** * 订阅审计日志的记录,并进行入库操作 */ - @MqttSubscribe(value = "/userLog") +// @MqttSubscribe(value = "/userLog") public void subUserLog(String topic, MqttMessage message, @Payload String payload) { if(Objects.isNull(jsonObject)){ jsonObject = (JSONObject) redisUtil.getObjectByKey(RedisKeyEnum.USER_ROLE_TYPE_KEY.getKey()); @@ -86,7 +82,7 @@ public class MqttMessageHandler { /** * 订阅审计日志的记录,并进行入库操作 */ - @MqttSubscribe(value = "/userLogEmailPush") +// @MqttSubscribe(value = "/userLogEmailPush") public void subUserLogEmail(String topic, MqttMessage message, @Payload String payload) { LogInfoDTO auditLogVO = PubUtils.json2obj(new String(message.getPayload(), StandardCharsets.UTF_8),LogInfoDTO.class); List data = userFeignClient.getUserListByRoleCode("audit_manager").getData(); diff --git a/pqs-system/system-boot/src/main/java/com/njcn/system/service/impl/AuditServiceImpl.java b/pqs-system/system-boot/src/main/java/com/njcn/system/service/impl/AuditServiceImpl.java index 2388ddf73..5a79c6753 100644 --- a/pqs-system/system-boot/src/main/java/com/njcn/system/service/impl/AuditServiceImpl.java +++ b/pqs-system/system-boot/src/main/java/com/njcn/system/service/impl/AuditServiceImpl.java @@ -21,7 +21,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.github.tocrhz.mqtt.publisher.MqttPublisher; import com.nimbusds.jose.JWSObject; import com.njcn.common.config.GeneralInfo; import com.njcn.common.pojo.constant.OperateType; @@ -37,6 +36,8 @@ import com.njcn.db.constant.DbConstant; import com.njcn.oss.constant.GeneralConstant; import com.njcn.oss.constant.OssPath; import com.njcn.oss.utils.FileStorageUtil; +import com.njcn.redis.pojo.enums.RedisKeyEnum; +import com.njcn.redis.utils.RedisMessageQueueUtil; import com.njcn.redis.utils.RedisUtil; import com.njcn.system.enums.SystemResponseEnum; import com.njcn.system.excel.UserLogExcel; @@ -52,6 +53,7 @@ import com.njcn.user.api.UserFeignClient; import com.njcn.user.pojo.po.User; import com.njcn.web.utils.RequestUtil; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.compress.utils.IOUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; @@ -76,11 +78,12 @@ import static com.njcn.common.pojo.constant.LogInfo.UNKNOWN_USER; */ @Service @RequiredArgsConstructor +@Slf4j public class AuditServiceImpl extends ServiceImpl implements AuditService { private final AuditMapper auditMapper; - @Value("${spring.datasource.druid.url}") + @Value("${spring.datasource.dynamic.datasource.sjzx.url}") private String urls; private final GeneralInfo generalInfo; @@ -93,7 +96,15 @@ public class AuditServiceImpl extends ServiceImpl implem private final IConfigService iConfigService; - private final MqttPublisher publisher; + /** + * mqtt处理日志异步发布 + */ +// private final MqttPublisher publisher; + + /** + * redis队列处理日志异步发布 + */ + private final RedisMessageQueueUtil redisMessageQueueUtil; private final FileStorageUtil fileStorageUtil; @@ -188,7 +199,11 @@ public class AuditServiceImpl extends ServiceImpl implem if (auditParam.isExport()) { methodDescribe = "审计日志列表导出"; LogInfoDTO logInfoDTO = new LogInfoDTO(loginName, userName, ip, methodDescribe, operateType, "失败".equalsIgnoreCase(result) ? 0 : 1, "", severity, "业务事件".equalsIgnoreCase(type) ? 0 : 1, generalInfo.getMicroServiceName(), userIndex, LocalDateTime.now()); - publisher.send("/userLog", PubUtils.obj2json(logInfoDTO), 2, false); + redisMessageQueueUtil.pushMessage( + RedisKeyEnum.USER_LOG_QUEUE.getKey(), + PubUtils.obj2json(logInfoDTO) + ); +// publisher.send("/userLog", PubUtils.obj2json(logInfoDTO), 2, false); } else { if (StrUtil.isNotBlank(auditParam.getSortBy()) && StrUtil.isNotBlank(auditParam.getOrderBy())) { methodDescribe = methodDescribe.concat("并以") @@ -197,7 +212,11 @@ public class AuditServiceImpl extends ServiceImpl implem .concat(DbConstant.DESC.equalsIgnoreCase(auditParam.getOrderBy()) ? "降序" : "升序") .concat("查询"); LogInfoDTO logInfoDTO = new LogInfoDTO(loginName, userName, ip, methodDescribe, operateType, "失败".equalsIgnoreCase(result) ? 0 : 1, "", severity, "业务事件".equalsIgnoreCase(type) ? 0 : 1, generalInfo.getMicroServiceName(), userIndex, LocalDateTime.now()); - publisher.send("/userLog", PubUtils.obj2json(logInfoDTO), 2, false); + redisMessageQueueUtil.pushMessage( + RedisKeyEnum.USER_LOG_QUEUE.getKey(), + PubUtils.obj2json(logInfoDTO) + ); +// publisher.send("/userLog", PubUtils.obj2json(logInfoDTO), 2, false); } } @@ -418,8 +437,41 @@ public class AuditServiceImpl extends ServiceImpl implem @Override public Float getMemoInfo() { - String schema = urls.substring(urls.lastIndexOf("/") + 1, urls.lastIndexOf("?")); - return this.baseMapper.getMemoInfo(schema); + // 1. 判空兜底,防止@Value注入为空/空字符串 + if (StrUtil.isBlank(urls)) { + log.error("getMemoInfo error: 数据库链接地址urls为空,无法截取schema"); + return 0.0F; + } + String schema = null; + try { + // 2. 先获取最后一个/的下标,截取库名起始位 + int lastSlashIndex = urls.lastIndexOf("/"); + // 3. 先获取?的下标,截取库名结束位 + int questionMarkIndex = urls.indexOf("?"); + // 4. 兼容两种场景:有问号参数、无问号参数 + if (lastSlashIndex > -1) { + if (questionMarkIndex > lastSlashIndex) { + // 正常场景:url带?后缀参数 → 截取 / 和 ? 之间的库名 + schema = urls.substring(lastSlashIndex + 1, questionMarkIndex); + } else { + // 兼容场景:url不带?后缀参数 → 截取 / 之后的全部内容作为库名 + schema = urls.substring(lastSlashIndex + 1); + } + } + } catch (Exception e) { + // 5. 捕获所有异常(下标越界、格式异常等),兜底处理 + log.error("getMemoInfo 截取数据库schema失败,urls={}, 异常信息:{}", urls, e); + return 0.0F; + } + // 6. 最终判空,防止截取结果为空 + if (StrUtil.isBlank(schema)) { + log.error("getMemoInfo 截取到的数据库schema为空,urls={}", urls); + return 0.0F; + } + // 7. 调用mapper查询,返回结果 + Float memoInfo = this.baseMapper.getMemoInfo(schema); + // 8. 兼容mapper返回null的情况,避免接口返回null报错 + return ObjectUtil.isNull(memoInfo) ? 0.0F : memoInfo; } @Override