package com.njcn.harmonic.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
import com.njcn.common.pojo.enums.common.ServerEnum;
import com.njcn.common.utils.HarmonicTimesUtil;
import com.njcn.common.utils.PubUtils;
import com.njcn.device.biz.commApi.CommTerminalGeneralClient;
import com.njcn.device.biz.pojo.dto.DeptGetChildrenMoreDTO;
import com.njcn.device.biz.pojo.dto.LineDevGetDTO;
import com.njcn.device.biz.pojo.param.DeptGetLineParam;
import com.njcn.device.biz.pojo.po.Overlimit;
import com.njcn.device.pq.api.LineFeignClient;
import com.njcn.harmonic.api.RStatLimitRateDClient;
import com.njcn.harmonic.mapper.PmsLineWarningMapper;
import com.njcn.harmonic.pojo.param.OnlineParam;
import com.njcn.harmonic.pojo.param.RStatLimitQueryParam;
import com.njcn.harmonic.pojo.po.PmsLineWarning;
import com.njcn.harmonic.pojo.po.day.RStatLimitRateDPO;
import com.njcn.harmonic.pojo.vo.LineLimitDetailVo;
import com.njcn.harmonic.pojo.vo.PmsOnlineVo;
import com.njcn.harmonic.pojo.vo.RStatLimitTargetVO;
import com.njcn.harmonic.service.IPmsLineWarningService;
import com.njcn.influx.constant.InfluxDbSqlConstant;
import com.njcn.influx.imapper.*;
import com.njcn.influx.pojo.po.*;
import com.njcn.influx.query.InfluxQueryWrapper;
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 com.njcn.user.api.DeptFeignClient;
import com.njcn.user.pojo.po.Dept;
import com.njcn.web.factory.PageFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Method;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 监测点每日稳态指标超标天数统计表 服务实现类
 * </p>
 *
 * @author xy
 * @since 2024-06-17
 */
@Service
@RequiredArgsConstructor
public class PmsLineWarningServiceImpl extends MppServiceImpl<PmsLineWarningMapper, PmsLineWarning> implements IPmsLineWarningService {

    private final DicDataFeignClient dicDataFeignClient;
    private final RStatLimitRateDClient limitRateDClient;
    private final CommTerminalGeneralClient commTerminalGeneralClient;
    private final LineFeignClient lineFeignClient;
    private final DeptFeignClient deptFeignClient;

    private final DataVMapper dataVMapper;
    private final DataIMapper dataIMapper;
    private final DataHarmRateVMapper dataHarmRateVMapper;
    private final DataInHarmVMapper dataInHarmVMapper;
    private final DataPltMapper dataPltMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addHeBeiNorthLineWarning(String startTime, String endTime) {
        List<PmsLineWarning> result = new ArrayList<>();
        //获取指标集合(10个指标)
        List<DictData> dataList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.STEADY_STATIS.getCode()).getData();
        Map<String, DictData> targetMap = dataList.stream().collect(Collectors.toMap(DictData::getCode, Function.identity()));
        //获取监测点和部门表关系
        Dept data = deptFeignClient.getRootDept().getData();
        DeptGetLineParam deptGetLineParam = new DeptGetLineParam();
        deptGetLineParam.setDeptId(data.getId());
        List<DeptGetChildrenMoreDTO> list = commTerminalGeneralClient.deptGetLine(deptGetLineParam).getData();
        List<LineDevGetDTO> dtoList = new ArrayList<>();
        for (DeptGetChildrenMoreDTO dto : list) {
            if (!CollectionUtils.isEmpty(dto.getLineBaseList())) {
                dtoList = Stream.concat(dtoList.stream(), dto.getLineBaseList().stream())
                        .collect(Collectors.collectingAndThen(Collectors.toSet(), ArrayList::new));
            }
        }
        if (!CollectionUtils.isEmpty(dtoList)) {
            //获取监测点按时间统计越限天数
            LocalDate firstDayOfMonth = Objects.isNull(startTime) ? LocalDate.now().minusDays(1).with(TemporalAdjusters.firstDayOfMonth()) : LocalDate.parse(startTime);
            String date = Objects.isNull(startTime) ? DateUtil.format(firstDayOfMonth.atStartOfDay(), DatePattern.NORM_DATE_PATTERN) : startTime;
            String endDate = Objects.isNull(endTime) ? DateUtil.format(LocalDateTime.now().minusDays(1), DatePattern.NORM_DATE_PATTERN) : endTime;
            RStatLimitQueryParam rStatLimitQueryParam = new RStatLimitQueryParam(null, date, endDate);
            List<RStatLimitTargetVO> limitTarget = limitRateDClient.monitorOverLimitDays(rStatLimitQueryParam).getData();
            Map<String, RStatLimitTargetVO> limitMap = limitTarget.stream().collect(Collectors.toMap(RStatLimitTargetVO::getLineId, Function.identity()));
            for (LineDevGetDTO item : dtoList) {
                if (Objects.isNull(limitMap.get(item.getPointId()))) {
                    continue;
                }
                //频率偏差
                PmsLineWarning l1 = overData(firstDayOfMonth, item.getPointId(), item.getUnitId(), targetMap.get(DicDataEnum.FREQUENCY_DEV.getCode()).getId(), limitMap.get(item.getPointId()).getFreqDevOvertime());
                //电压偏差
                PmsLineWarning l2 = overData(firstDayOfMonth, item.getPointId(), item.getUnitId(), targetMap.get(DicDataEnum.VOLTAGE_DEV.getCode()).getId(), limitMap.get(item.getPointId()).getVoltageDevOvertime());
                //长时闪变
                PmsLineWarning l3 = overData(firstDayOfMonth, item.getPointId(), item.getUnitId(), targetMap.get(DicDataEnum.FLICKER.getCode()).getId(), limitMap.get(item.getPointId()).getFlickerOvertime());
                //谐波电压
                PmsLineWarning l4 = overData(firstDayOfMonth, item.getPointId(), item.getUnitId(), targetMap.get(DicDataEnum.HARMONIC_VOLTAGE.getCode()).getId(), limitMap.get(item.getPointId()).getUharmOvertime());
                //谐波电流
                PmsLineWarning l5 = overData(firstDayOfMonth, item.getPointId(), item.getUnitId(), targetMap.get(DicDataEnum.HARMONIC_CURRENT.getCode()).getId(), limitMap.get(item.getPointId()).getIharmOvertime());
                //间谐波电压
                PmsLineWarning l6 = overData(firstDayOfMonth, item.getPointId(), item.getUnitId(), targetMap.get(DicDataEnum.INTERHARMONIC_VOLTAGE.getCode()).getId(), limitMap.get(item.getPointId()).getInuharmOvertime());
                //负序电压不平衡度
                PmsLineWarning l7 = overData(firstDayOfMonth, item.getPointId(), item.getUnitId(), targetMap.get(DicDataEnum.PHASE_VOLTAGE.getCode()).getId(), limitMap.get(item.getPointId()).getUbalanceOvertime());
                //负序电流
                PmsLineWarning l8 = overData(firstDayOfMonth, item.getPointId(), item.getUnitId(), targetMap.get(DicDataEnum.NEG_CURRENT.getCode()).getId(), limitMap.get(item.getPointId()).getINegOvertime());
                //电压总谐波畸变率
                PmsLineWarning l9 = overData(firstDayOfMonth, item.getPointId(), item.getUnitId(), targetMap.get(DicDataEnum.THD_V.getCode()).getId(), limitMap.get(item.getPointId()).getUaberranceOvertime());
                //总稳态指标
                PmsLineWarning l10 = overData(firstDayOfMonth, item.getPointId(), item.getUnitId(), targetMap.get(DicDataEnum.TOTAL_INDICATOR.getCode()).getId(), limitMap.get(item.getPointId()).getAllOvertime());
                result.addAll(Arrays.asList(l1, l2, l3, l4, l5, l6, l7, l8, l9, l10));
            }
            this.saveOrUpdateBatchByMultiId(result);
        }
    }

    @Override
    public Page<PmsOnlineVo> getLineWarningList(OnlineParam param) {
        DeptGetLineParam deptGetLineParam = new DeptGetLineParam();
        deptGetLineParam.setDeptId(param.getDeptId());
        deptGetLineParam.setServerName(ServerEnum.HARMONIC.getName());
        List<DeptGetChildrenMoreDTO> list = commTerminalGeneralClient.deptGetLine(deptGetLineParam).getData();
        List<String> lineList = list.stream()
                .flatMap(dto -> dto.getLineBaseList().stream().map(LineDevGetDTO::getPointId))
                .distinct()
                .collect(Collectors.toList());
        QueryWrapper<PmsLineWarning> queryWrapper = new QueryWrapper<>();
        queryWrapper.between("p1.alarm_time", param.getSearchBeginTime(), param.getSearchEndTime());
        //监测点id
        if (CollUtil.isNotEmpty(lineList)) {
            queryWrapper.in("p1.line_id", lineList);
        }
        //监测点类型
        if (StringUtils.isNotBlank(param.getLineType())) {
            if (Objects.equals(param.getLineType(),"0")) {
                queryWrapper.eq("p2.Power_Flag", "101");
            } else {
                queryWrapper.eq("p2.Power_Flag", "102");
            }
        }
        //指标判断
        if (CollUtil.isNotEmpty(param.getTargetList())) {
            queryWrapper.in("p1.target_type", param.getTargetList());
        }
        if (Objects.nonNull(param.getAlarmThreshold())) {
            queryWrapper.ge("p1.over_limit_day", param.getAlarmThreshold());
        }
        queryWrapper.orderBy(true, true, "p2.Org_Name", "p2.Powerr_Name", "p3.`Name`");
        return this.baseMapper.page(new Page<>(PageFactory.getPageNum(param), PageFactory.getPageSize(param)), queryWrapper);
    }

    @Override
    public List<LineLimitDetailVo> getOverLimitDetail(OnlineParam.DetailParam param) {
        List<LineLimitDetailVo> result = new ArrayList<>();
        String targetCode = dicDataFeignClient.getDicDataById(param.getTargetId()).getData().getCode();
        //获取监测点统计间隔
        Integer timeInterval = commTerminalGeneralClient.getMonitorDetail(param.getLineId()).getData().getInterval();
        //获取限值
        Overlimit overlimit = commTerminalGeneralClient.getOverLimitData(param.getLineId()).getData();
        //处理数据
        List<LineLimitDetailVo> data = chanelTarget(param, overlimit, timeInterval, targetCode);
        if (CollUtil.isNotEmpty(data)) {
            result = data.stream().sorted(Comparator.comparing(LineLimitDetailVo::getTime)).collect(Collectors.toList());
        }
        return result;
    }

    //指标数据处理
    public List<LineLimitDetailVo> chanelTarget(OnlineParam.DetailParam param, Overlimit overlimit, Integer timeInterval, String targetCode) {
        List<LineLimitDetailVo> result = new ArrayList<>(), finalList = new ArrayList<>();
        //频率偏差
        if (Objects.equals(targetCode, DicDataEnum.FREQUENCY_DEV.getCode()) || Objects.equals(targetCode, DicDataEnum.TOTAL_INDICATOR.getCode())) {
            List<RStatLimitRateDPO> list = limitRateDClient.getOverData(param.getLineId(), param.getSearchBeginTime(), param.getSearchEndTime(), 1).getData();
            if (CollUtil.isNotEmpty(list)) {
                list.forEach(item -> {
                    String time = item.getTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN));
                    double maxData = getFreqDev(param.getLineId()
                            , time + " 00:00:00"
                            , time + " 23:59:59"
                    ).get(0).getFreqDev();
                    channelEachData(item, maxData > 0 ? overlimit.getFreqDev() : -overlimit.getFreqDev(), "getFreqDev", result, DicDataEnum.FREQUENCY_DEV.getName(), timeInterval, maxData);
                });
            }
        }
        //电压偏差
        if (Objects.equals(targetCode, DicDataEnum.VOLTAGE_DEV.getCode()) || Objects.equals(targetCode, DicDataEnum.TOTAL_INDICATOR.getCode())) {
            List<RStatLimitRateDPO> list = limitRateDClient.getOverData(param.getLineId(), param.getSearchBeginTime(), param.getSearchEndTime(), 2).getData();
            if (CollUtil.isNotEmpty(list)) {
                list.forEach(item -> {
                    Float overLimit;
                    Double maxData;
                    String time = item.getTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN));
                    List<DataV> voltageList = getVoltageDev(param.getLineId()
                            , time + " 00:00:00"
                            , time + " 23:59:59"
                    );
                    List<Double> voltage = voltageList.stream().map(DataV::getVuDev).collect(Collectors.toList());
                    if (Math.abs(voltage.get(0)) >= Math.abs(voltage.get(1))) {
                        overLimit = overlimit.getUvoltageDev();
                        maxData = voltage.get(0);
                    } else {
                        overLimit = overlimit.getVoltageDev();
                        maxData = voltage.get(1);
                    }
                    channelEachData(item, overLimit, "getVoltageDev", result, DicDataEnum.VOLTAGE_DEV.getName(), timeInterval, maxData);
                });
            }
        }
        //长时闪变
        if (Objects.equals(targetCode, DicDataEnum.FLICKER.getCode()) || Objects.equals(targetCode, DicDataEnum.TOTAL_INDICATOR.getCode())) {
            List<RStatLimitRateDPO> list = limitRateDClient.getOverData(param.getLineId(), param.getSearchBeginTime(), param.getSearchEndTime(), 3).getData();
            if (CollUtil.isNotEmpty(list)) {
                list.forEach(item -> {
                    String time = item.getTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN));
                    double maxData = getFlicker(param.getLineId()
                            , time + " 00:00:00"
                            , time + " 23:59:59"
                    ).get(0).getPlt();
                    channelEachData(item, overlimit.getFlicker(), "getFlicker", result, DicDataEnum.FLICKER.getName(), timeInterval, maxData);
                });
            }
        }
        //电压总谐波畸变率
        if (Objects.equals(targetCode, DicDataEnum.THD_V.getCode())) {
            List<RStatLimitRateDPO> list = limitRateDClient.getOverData(param.getLineId(), param.getSearchBeginTime(), param.getSearchEndTime(), 4).getData();
            if (CollUtil.isNotEmpty(list)) {
                list.forEach(item -> {
                    String time = item.getTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN));
                    double maxData = getVThd(param.getLineId()
                            , time + " 00:00:00"
                            , time + " 23:59:59"
                    ).get(0).getVThd();
                    channelEachData(item, overlimit.getUaberrance(), "getUaberrance", result, DicDataEnum.THD_V.getName(), timeInterval, maxData);
                });
            }
        }
        //谐波电压
        if (Objects.equals(targetCode, DicDataEnum.HARMONIC_VOLTAGE.getCode()) || Objects.equals(targetCode, DicDataEnum.TOTAL_INDICATOR.getCode())) {
            //电压总谐波畸变率
            List<RStatLimitRateDPO> list = limitRateDClient.getOverData(param.getLineId(), param.getSearchBeginTime(), param.getSearchEndTime(), 4).getData();
            if (CollUtil.isNotEmpty(list)) {
                list.forEach(item -> {
                    String time = item.getTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN));
                    double maxData = getVThd(param.getLineId()
                            , time + " 00:00:00"
                            , time + " 23:59:59"
                    ).get(0).getVThd();
                    channelEachData(item, overlimit.getUaberrance(), "getUaberrance", result, DicDataEnum.THD_V.getName(), timeInterval, maxData);
                });
            }
            //谐波电压含有率2~25次
            List<RStatLimitRateDPO> list2 = limitRateDClient.getOverData(param.getLineId(), param.getSearchBeginTime(), param.getSearchEndTime(), 7).getData();
            if (CollUtil.isNotEmpty(list2)) {
                list2.forEach(item -> {
                    String time = item.getTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN));
                    DataHarmRateV dataHarmRateV = getDataHarmRateV(param.getLineId()
                            , time + " 00:00:00"
                            , time + " 23:59:59").get(0);
                    channelHarmonicData(dataHarmRateV, null, null, item, overlimit, result, "getUharm", DicDataEnum.HARMONIC_VOLTAGE.getName(), timeInterval, 2, 25);
                });
            }
        }
        //谐波电流
        if (Objects.equals(targetCode, DicDataEnum.HARMONIC_CURRENT.getCode()) || Objects.equals(targetCode, DicDataEnum.TOTAL_INDICATOR.getCode())) {
            List<RStatLimitRateDPO> list = limitRateDClient.getOverData(param.getLineId(), param.getSearchBeginTime(), param.getSearchEndTime(), 8).getData();
            if (CollUtil.isNotEmpty(list)) {
                list.forEach(item -> {
                    String time = item.getTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN));
                    DataI dataI = getDataI(param.getLineId()
                            , time + " 00:00:00"
                            , time + " 23:59:59").get(0);
                    channelHarmonicData(null, dataI, null, item, overlimit, result, "getIharm", DicDataEnum.HARMONIC_CURRENT.getName(), timeInterval, 2, 25);
                });
            }
        }
        //间谐波电压
        if (Objects.equals(targetCode, DicDataEnum.INTERHARMONIC_VOLTAGE.getCode()) || Objects.equals(targetCode, DicDataEnum.TOTAL_INDICATOR.getCode())) {
            List<RStatLimitRateDPO> list = limitRateDClient.getOverData(param.getLineId(), param.getSearchBeginTime(), param.getSearchEndTime(), 9).getData();
            if (CollUtil.isNotEmpty(list)) {
                list.forEach(item -> {
                    String time = item.getTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN));
                    DataInHarmV dataInHarmV = getDataInHarmV(param.getLineId()
                            , time + " 00:00:00"
                            , time + " 23:59:59").get(0);
                    channelHarmonicData(null, null, dataInHarmV, item, overlimit, result, "getInuharm", DicDataEnum.INTERHARMONIC_VOLTAGE.getName(), timeInterval, 1, 16);
                });
            }
        }
        //负序电压不平衡度
        if (Objects.equals(targetCode, DicDataEnum.PHASE_VOLTAGE.getCode()) || Objects.equals(targetCode, DicDataEnum.TOTAL_INDICATOR.getCode())) {
            List<RStatLimitRateDPO> list = limitRateDClient.getOverData(param.getLineId(), param.getSearchBeginTime(), param.getSearchEndTime(), 5).getData();
            if (CollUtil.isNotEmpty(list)) {
                list.forEach(item -> {
                    String time = item.getTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN));
                    double maxData = getUnbalance(param.getLineId()
                            , time + " 00:00:00"
                            , time + " 23:59:59"
                    ).get(0).getVUnbalance();
                    channelEachData(item, overlimit.getUbalance(), "getUbalance", result, DicDataEnum.PHASE_VOLTAGE.getName(), timeInterval, maxData);
                });
            }
        }
        //负序电流
        if (Objects.equals(targetCode, DicDataEnum.NEG_CURRENT.getCode()) || Objects.equals(targetCode, DicDataEnum.TOTAL_INDICATOR.getCode())) {
            List<RStatLimitRateDPO> list = limitRateDClient.getOverData(param.getLineId(), param.getSearchBeginTime(), param.getSearchEndTime(), 6).getData();
            if (CollUtil.isNotEmpty(list)) {
                list.forEach(item -> {
                    String time = item.getTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN));
                    double maxData = getINeg(param.getLineId()
                            , time + " 00:00:00"
                            , time + " 23:59:59"
                    ).get(0).getINeg();
                    channelEachData(item, overlimit.getINeg(), "getINeg", result, DicDataEnum.NEG_CURRENT.getName(), timeInterval, maxData);
                });
            }
        }
        if (CollUtil.isNotEmpty(result)) {
            Map<LocalDate, List<LineLimitDetailVo>> map = result.stream().collect(Collectors.groupingBy(LineLimitDetailVo::getTime, LinkedHashMap::new, Collectors.toList()));
            map.forEach((k, v) -> {
                StringBuilder describe = new StringBuilder();
                LineLimitDetailVo lineLimitDetailVo = new LineLimitDetailVo();
                lineLimitDetailVo.setTime(k);
                v.forEach(item -> {
                    describe.append(item.getOverLimitInfo());
                });
                lineLimitDetailVo.setOverLimitInfo(describe.toString());
                finalList.add(lineLimitDetailVo);
            });
        }
        return finalList;
    }

    //处理单指标
    public void channelEachData(RStatLimitRateDPO dpo, float limit, String getColum, List<LineLimitDetailVo> result, String targetName, Integer timeInterval, double maxData) {
        try {
            Class<?> clazz = dpo.getClass();
            String methodName = getColum + "Overtime";
            Method method;
            method = clazz.getMethod(methodName);
            int value = (int) method.invoke(dpo);
            LineLimitDetailVo vo = new LineLimitDetailVo();
            vo.setTime(dpo.getTime());
            vo.setOverLimitInfo(targetName + "最大幅值:" + PubUtils.doubleRound(2, maxData) + ",限值:" + limit + ",超标时间:" + value * timeInterval + "分钟;");
            result.add(vo);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //处理谐波数据 谐波电压、谐波电流、间谐波电压
    public void channelHarmonicData(DataHarmRateV dataHarmRateV, DataI dataI, DataInHarmV dataInHarmV, RStatLimitRateDPO dpo, Overlimit overlimit, List<LineLimitDetailVo> result, String getColum, String targetName, Integer timeInterval, Integer startTimes, Integer endTimes) {
        LinkedHashMap<Integer, Integer> overMap = new LinkedHashMap<>();
        StringBuilder describe = new StringBuilder();
        LineLimitDetailVo vo = new LineLimitDetailVo();
        vo.setTime(dpo.getTime());
        //查看具体哪几次超标
        Class<?> clazz = dpo.getClass();
        for (int i = startTimes; i <= endTimes; i++) {
            String methodName = getColum + i + "Overtime";
            try {
                Method method = clazz.getMethod(methodName);
                int value = (int) method.invoke(dpo);
                if (value > 0) {
                    overMap.put(i, value);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        Class<?> clazz2 = null;
        String targetName2 = null;
        double value2;
        if (Objects.nonNull(dataHarmRateV)) {
            clazz2 = dataHarmRateV.getClass();
            targetName2 = "getV";
        } else if (Objects.nonNull(dataI)) {
            clazz2 = dataI.getClass();
            targetName2 = "getI";
        } else if (Objects.nonNull(dataInHarmV)) {
            clazz2 = dataInHarmV.getClass();
            targetName2 = "getV";
        }
        for (Integer key : overMap.keySet()) {
            int value = overMap.get(key);
            String methodName = targetName2 + key;
            Method method;
            try {
                method = clazz2.getMethod(methodName);
                if (Objects.nonNull(dataHarmRateV)) {
                    value2 = (double) method.invoke(dataHarmRateV);
                    describe.append(key).append("次").append(targetName).append("CP95值最大幅值:").append(PubUtils.doubleRound(2, value2)).append("%,限值:").append(getOverLimitData(overlimit, getColum, key)).append("%,超标时间:").append(value * timeInterval).append("分钟;");
                } else if (Objects.nonNull(dataI)) {
                    value2 = (double) method.invoke(dataI);
                    describe.append(key).append("次").append(targetName).append("CP95值最大幅值:").append(PubUtils.doubleRound(2, value2)).append("%,限值:").append(getOverLimitData(overlimit, getColum, key)).append("%,超标时间:").append(value * timeInterval).append("分钟;");
                } else if (Objects.nonNull(dataInHarmV)) {
                    value2 = (double) method.invoke(dataInHarmV);
                    describe.append((key - 0.5)).append("次").append(targetName).append("CP95值最大幅值:").append(PubUtils.doubleRound(2, value2)).append("%,限值:").append(getOverLimitData(overlimit, getColum, key)).append("%,超标时间:").append(value * timeInterval).append("分钟;");
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        vo.setOverLimitInfo(describe.toString().trim());
        result.add(vo);
    }

    public PmsLineWarning overData(LocalDate date, String lineId, String deptId, String codeId, Integer overDays) {
        PmsLineWarning lineWarning = new PmsLineWarning();
        lineWarning.setAlarmTime(date);
        lineWarning.setDeptId(deptId);
        lineWarning.setLineId(lineId);
        lineWarning.setTargetType(codeId);
        lineWarning.setOverLimitDay(overDays);
        return lineWarning;
    }

    private float getOverLimitData(Overlimit overlimit, String targetName, Integer times) {
        float result;
        Class<?> clazz = overlimit.getClass();
        String methodName = targetName + times;
        try {
            Method method = clazz.getMethod(methodName);
            result = (float) method.invoke(overlimit);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    /**
     * 获取频率偏差-日最大值-最大值
     */
    public List<DataV> getFreqDev(String lineIndex, String startTime, String endTime) {
        InfluxQueryWrapper influxQueryWrapper2 = new InfluxQueryWrapper(DataV.class);
        influxQueryWrapper2.eq(DataV::getLineId, lineIndex)
                .eq(DataV::getValueType, InfluxDbSqlConstant.MAX)
                .eq(DataV::getPhaseType, "T")
                .max(DataV::getFreqDev)
                .between(DataV::getTime, startTime, endTime);
        return dataVMapper.getStatisticsByWraper(influxQueryWrapper2);
    }

    /**
     * 获取电压偏差-日最大值&&日最小值 日最大值的最大值 日最小值的最小值
     */
    public List<DataV> getVoltageDev(String lineIndex, String startTime, String endTime) {
        InfluxQueryWrapper influxQueryWrapper = new InfluxQueryWrapper(DataV.class);
        influxQueryWrapper.eq(DataV::getLineId, lineIndex)
                .eq(DataV::getValueType, InfluxDbSqlConstant.MIN)
                .regular(DataV::getPhaseType, Arrays.asList("A", "B", "C"))
                .min(DataV::getVuDev)
                .between(DataV::getTime, startTime, endTime);
        List<DataV> result = new ArrayList<>(dataVMapper.getStatisticsByWraper(influxQueryWrapper));
        InfluxQueryWrapper influxQueryWrapper2 = new InfluxQueryWrapper(DataV.class);
        influxQueryWrapper2.eq(DataV::getLineId, lineIndex)
                .eq(DataV::getValueType, InfluxDbSqlConstant.MAX)
                .regular(DataV::getPhaseType, Arrays.asList("A", "B", "C"))
                .max(DataV::getVuDev)
                .between(DataV::getTime, startTime, endTime);
        result.addAll(dataVMapper.getStatisticsByWraper(influxQueryWrapper2));
        return result;
    }

    /**
     * 获取长时闪变-日最大值-最大值
     */
    public List<DataPlt> getFlicker(String lineIndex, String startTime, String endTime) {
        InfluxQueryWrapper influxQueryWrapper = new InfluxQueryWrapper(DataPlt.class);
        influxQueryWrapper.eq(DataPlt::getLineId, lineIndex)
                .regular(DataPlt::getPhaseType, Arrays.asList("A", "B", "C"))
                .max(DataPlt::getPlt)
                .between(DataPlt::getTime, startTime, endTime);
        return dataPltMapper.getStatisticsByWraper(influxQueryWrapper);
    }

    /**
     * 获取电压总谐波畸变率-日CP95-最大值
     */
    public List<DataV> getVThd(String lineIndex, String startTime, String endTime) {
        InfluxQueryWrapper influxQueryWrapper = new InfluxQueryWrapper(DataV.class);
        influxQueryWrapper.eq(DataV::getLineId, lineIndex)
                .eq(DataV::getValueType, InfluxDbSqlConstant.CP95)
                .regular(DataV::getPhaseType, Arrays.asList("A", "B", "C"))
                .max(DataV::getVThd)
                .between(DataV::getTime, startTime, endTime);
        return dataVMapper.getStatisticsByWraper(influxQueryWrapper);
    }

    /**
     * 获取负序电压不平衡度-日最大值-最大值
     */
    public List<DataV> getUnbalance(String lineIndex, String startTime, String endTime) {
        InfluxQueryWrapper influxQueryWrapper = new InfluxQueryWrapper(DataV.class);
        influxQueryWrapper.eq(DataV::getLineId, lineIndex)
                .eq(DataV::getValueType, InfluxDbSqlConstant.MAX)
                .eq(DataV::getPhaseType, "T")
                .max(DataV::getVUnbalance)
                .between(DataV::getTime, startTime, endTime);
        return dataVMapper.getStatisticsByWraper(influxQueryWrapper);
    }

    /**
     * 获取负序电流-日最大值-最大值
     */
    public List<DataI> getINeg(String lineIndex, String startTime, String endTime) {
        InfluxQueryWrapper influxQueryWrapper = new InfluxQueryWrapper(DataI.class);
        influxQueryWrapper.eq(DataI::getLineId, lineIndex)
                .eq(DataI::getValueType, InfluxDbSqlConstant.MAX)
                .eq(DataI::getPhaseType, "T")
                .max(DataI::getINeg)
                .between(DataI::getTime, startTime, endTime);
        return dataIMapper.getStatisticsByWraper(influxQueryWrapper);
    }

    /**
     * 获取谐波电压含有率 2~25次数据
     */
    public List<DataHarmRateV> getDataHarmRateV(String lineIndex, String startTime, String endTime) {
        InfluxQueryWrapper influxQueryWrapper = new InfluxQueryWrapper(DataHarmRateV.class);
        influxQueryWrapper.maxSamePrefixAndSuffix(InfluxDbSqlConstant.V, "", HarmonicTimesUtil.harmonicTimesList(2, 25, 1));
        influxQueryWrapper.eq(DataHarmRateV::getLineId, lineIndex)
                .eq(DataHarmRateV::getValueType, InfluxDbSqlConstant.CP95)
                .regular(DataHarmRateV::getPhaseType, Arrays.asList("A", "B", "C"))
                .between(DataHarmRateV::getTime, startTime, endTime);
        return dataHarmRateVMapper.getStatisticsByWraper(influxQueryWrapper);
    }

    /**
     * 获取谐波电流含有率 2~25次数据
     */
    public List<DataI> getDataI(String lineIndex, String startTime, String endTime) {
        InfluxQueryWrapper influxQueryWrapper = new InfluxQueryWrapper(DataI.class);
        influxQueryWrapper.maxSamePrefixAndSuffix(InfluxDbSqlConstant.I, "", HarmonicTimesUtil.harmonicTimesList(2, 25, 1));
        influxQueryWrapper.eq(DataI::getLineId, lineIndex)
                .eq(DataI::getValueType, InfluxDbSqlConstant.CP95)
                .regular(DataI::getPhaseType, Arrays.asList("A", "B", "C"))
                .between(DataI::getTime, startTime, endTime);
        return dataIMapper.getStatisticsByWraper(influxQueryWrapper);
    }

    /**
     * 获取间谐波电压含有率 2~25次数据
     */
    public List<DataInHarmV> getDataInHarmV(String lineIndex, String startTime, String endTime) {
        InfluxQueryWrapper influxQueryWrapper = new InfluxQueryWrapper(DataInHarmV.class);
        influxQueryWrapper.maxSamePrefixAndSuffix(InfluxDbSqlConstant.V, "", HarmonicTimesUtil.harmonicTimesList(1, 16, 1));
        influxQueryWrapper.eq(DataInHarmV::getLineId, lineIndex)
                .eq(DataInHarmV::getValueType, InfluxDbSqlConstant.CP95)
                .regular(DataInHarmV::getPhaseType, Arrays.asList("A", "B", "C"))
                .between(DataInHarmV::getTime, startTime, endTime);
        return dataInHarmVMapper.getStatisticsByWraper(influxQueryWrapper);
    }
}
