package com.gyee.generation.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gyee.common.contant.ContantXk;
import com.gyee.common.model.PointData;
import com.gyee.generation.init.CacheContext;
import com.gyee.generation.model.auto.*;
import com.gyee.generation.model.vo.*;
import com.gyee.generation.service.auto.*;
import com.gyee.generation.util.DateUtils;
import com.gyee.generation.util.StringUtils;
import com.gyee.generation.util.realtimesource.IEdosUtil;
import com.gyee.generation.util.realtimesource.math.LineUtil;
import com.gyee.generation.util.redis.RedisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class PowerCurveFittingByTimeGfService {

    private static final Logger logger = LoggerFactory.getLogger(PowerCurveFittingByTimeService.class);
    @Resource
    private IEdosUtil edosUtil;

    @Value("${curvefitting.dimension}")
    private Integer dimension;
    @Value("${curvefitting.scale}")
    private Double scale;
    @Value("${initialcode}")
    private String initialcode;
    public Map<String, Double> windturbineCapacity;


    @Resource
    private RedisService redisService;
    @Resource
    private IProEconWtCurveFittingMonthService proEconWtCurveFittingMonthService;

    @Resource
    private IProEconWtCurveFittingYearService proEconWtCurveFittingYearService;
    @Resource
    private IProEconWtCurveFittingService proEconWtCurveFittingService;

    @Resource
    private IProEconCurveFittingMainService proEconCurveFittingMainService;
    @Resource
    private IProEconCurveFittingSubService proEconCurveFittingSubService;
    @Resource
    private IProEconCurveFittMonthMainService proEconCurveFittMonthMainService;
    @Resource
    private IProEconCurveFittMonthSubService proEconCurveFittMonthSubService;
    @Resource
    private IProEconWtPowerCurveFittingService proEconWtPowerCurveFittingService;

    @Resource
    private IProEconCurveFittYearSubService proEconCurveFittYearSubService;
    @Resource
    private IProEconCurveFittYearMainService proEconCurveFittYearMainService;


    public void cureFittingDay(Date recordDate) throws Exception {
        //日期变为昨天
        Date end = DateUtils.addDays(DateUtils.truncate(recordDate), -1);

        Calendar c = Calendar.getInstance();
        c.setTime(end);

        Date begin = DateUtils.addDays(end, -6);

        proEconWtCurveFittingService.deleteProEconWtCurveFittingGByDay(DateUtils.truncate(recordDate));
        proEconCurveFittingMainService.deleteProEconCurveFittingMainGByDay(DateUtils.truncate(recordDate));
        proEconCurveFittingSubService.deleteProEconCurveFittingSubGByDay(DateUtils.truncate(recordDate));
        Map<String, CureFittingVo> windMap = new HashMap<>();

        //初始化风机装机容量

        if (windturbineCapacity == null) {
            windturbineCapacity = new HashMap<>();
            Map<String, ProEconEquipmentmodel> modelMap = CacheContext.modelMap;
            for (ProBasicEquipment windturbine : CacheContext.wtls) {
                if (modelMap.containsKey(windturbine.getModelId())) {
                    windturbineCapacity.put(windturbine.getId(), modelMap.get(windturbine.getModelId()).getPowerProduction());
                }
            }
        }

        for (ProBasicEquipment wt : CacheContext.wtls) {
            String windturbineId = wt.getId();

            if (wt.getWindpowerstationId().contains(WpType.GDC.id)) {
                continue;
            }


            Map<String, ProBasicEquipmentPoint> windturbinetestingpointnewMap = CacheContext.wtpAimap.get(wt.getId());
            //设备有功功率
            String pointIdGL = null;
            //设备明细状态
            String pointIdZT = null;

            String pointIdFS = null;
            if (windturbinetestingpointnewMap.containsKey(ContantXk.CJ_SSFS)) {

                pointIdFS = windturbinetestingpointnewMap.get(ContantXk.CJ_SSFS).getNemCode();
            }
            if (windturbinetestingpointnewMap.containsKey(ContantXk.CJ_SSGL)) {

                pointIdGL = windturbinetestingpointnewMap.get(ContantXk.CJ_SSGL).getNemCode();
            }
            if (windturbinetestingpointnewMap.containsKey(ContantXk.MXZT)) {

                pointIdZT = windturbinetestingpointnewMap.get(ContantXk.MXZT).getNemCode();
            }

            CureFittingVo item = new CureFittingVo();

            item.setPointIdFS(pointIdFS);
            item.setPointIdZT(pointIdZT);
            item.setPointIdGL(pointIdGL);

            //获取标杆风机编号
            if (CacheContext.wtstandardmap.containsKey(wt.getId())) {
                item.setStandardId(CacheContext.wtstandardmap.get(wt.getId()));
            } else {
                item.setStandardId(wt.getId());
            }

            windMap.put(windturbineId, item);
        }


        for (String key : windMap.keySet()) {
            //初始化集合
            windMap.get(key).setYsjglPoints(new ArrayList<>());
            windMap.get(key).setYzyglPoints(new ArrayList<>());
            windMap.get(key).setRsjglPoints(new ArrayList<>());
            windMap.get(key).setRzyglPoints(new ArrayList<>());
            windMap.get(key).setNsjglPoints(new ArrayList<>());
            windMap.get(key).setNzyglPoints(new ArrayList<>());


            if (windMap.get(key).getPointIdGL() == null || windMap.get(key).getPointIdFS() == null || windMap.get(key).getPointIdZT() == null) {
                logger.info(key);
                continue;
            }


            //拟合日功率曲线
            curveFittingBuilder(begin, end, dimension, scale, windMap.get(key).getPointIdGL(), windMap.get(key).getPointIdFS(), windMap.get(key).getPointIdZT(), windMap.get(key).getRsjglPoints(), windMap.get(key).getRzyglPoints(), key);
            List<PointVo> vos = windMap.get(key).getRsjglPoints().stream().filter(it -> it.getX() >= 0 && it.getX() <= 1000).sorted(Comparator.comparing(PointVo::getX)).collect(Collectors.toList());
            windMap.get(key).setRsjglPoints(vos);
            vos = windMap.get(key).getRzyglPoints().stream().filter(it -> it.getX() >= 0 && it.getX() <= 1000).sorted(Comparator.comparing(PointVo::getX)).collect(Collectors.toList());
            windMap.get(key).setRzyglPoints(vos);

        }


        List<ProEconCurveFittingMain> mainls = new ArrayList<>();
        for (String key : windMap.keySet()) {

            Double modelpower = 1500.0;
            if (windturbineCapacity.containsKey(key)) {
                modelpower = windturbineCapacity.get(key);
            }


            //日的昨天
            List<PointVo> dayLastMonthPoints = new ArrayList<>();
            //日的去年同期
            List<PointVo> dayLastYearPoints = new ArrayList<>();
            //日标准功率
            List<PointVo> dayStandardPoints = new ArrayList<>();
            //保证功率
            List<PointVo> bzglpowerPoints = new ArrayList<>();


            if (CacheContext.wtstandardmap.containsKey(key)) {
                String standardId = CacheContext.wtstandardmap.get(key);
                if (StringUtils.notEmp(standardId)) {
                    if (windMap.containsKey(key)) {

                        dayStandardPoints = windMap.get(standardId).getRsjglPoints();
                    }
                }
            }


            //*********************************************日曲线偏差上个日和上一年记录**********************************************************/
            Date d1 = DateUtils.addDays(recordDate, -1);
            Date d2 = DateUtils.addYears(recordDate, -1);
            QueryWrapper<ProEconWtCurveFitting> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("record_date", d1).eq("windturbine_id", key);
            List<ProEconWtCurveFitting> wcfls = proEconWtCurveFittingService.list(queryWrapper)
                    .stream()
                    //                    .filter(i -> i.getWindturbineId().equals(key) &&
                    //                    i.getRecordDate().compareTo(d1) == 0)
                    .sorted(Comparator.comparing(ProEconWtCurveFitting::getSpeed)).collect(Collectors.toList());


            dayBuildPoints(wcfls, dayLastMonthPoints);

            QueryWrapper<ProEconWtCurveFitting> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.eq("record_date", d2).eq("windturbine_id", key);
            wcfls = proEconWtCurveFittingService.list(queryWrapper2).stream()
                    //                    .filter(i -> i.getWindturbineId().equals(key) &&
                    //                    i.getRecordDate().compareTo(d2) == 0)
                    .sorted(Comparator.comparing(ProEconWtCurveFitting::getSpeed)).collect(Collectors.toList());

            //与轶总的原始代码对比不一致，临时修改测试
            dayBuildPoints(wcfls, dayLastMonthPoints);
            //*********************************************日曲线偏差上个月和上一年记录**********************************************************/
            if (CacheContext.wtmap.containsKey(key)) {
                String modelid = CacheContext.wtmap.get(key).getModelId();
                if (StringUtils.notEmp(modelid)) {
                    //获取模型功率曲线
                    if (CacheContext.theoreticalPowerMap.containsKey(modelid)) {
                        for (Double speed : CacheContext.theoreticalPowerMap.get(modelid).keySet()) {
                            PointVo point = new PointVo();
                            point.setX(speed);
                            point.setY(CacheContext.theoreticalPowerMap.get(modelid).get(speed).getEnsurePower());

                            bzglpowerPoints.add(point);
                        }
                    }
                }
            }


            //*********************************************当日曲线偏差记录**********************************************************/
            QueryWrapper<ProEconCurveFittingMain> queryWrapper3 = new QueryWrapper<>();
            queryWrapper3.eq("record_date", recordDate).eq("windturbine_id", key);
            Optional<ProEconCurveFittingMain> cfmdayo = proEconCurveFittingMainService.list(queryWrapper3).stream()
                    //                    .filter(i -> i.getWindturbineId().equals(key)
                    //                    && i.getRecordDate().compareTo(recordDate) == 0)
                    .findFirst();
            ProEconCurveFittingMain cfmday;

            if (cfmdayo.isPresent()) {
                cfmday = cfmdayo.get();
                QueryWrapper<ProEconCurveFittingMain> wrapper = new QueryWrapper<>();
                wrapper.eq("id", cfmday.getId());
                proEconCurveFittingMainService.remove(wrapper);
            }

            cfmday = new ProEconCurveFittingMain();
            cfmday.setWindturbineId(key);
            cfmday.setRecordDate(DateUtils.truncate(recordDate));


            //日---实际/最优
            cfmday.setDeviationRate1(pcl(windMap.get(key).getRsjglPoints(), windMap.get(key).getRzyglPoints(), modelpower));
            //日---实际/保证
            cfmday.setDeviationRate2(pcl(windMap.get(key).getRsjglPoints(), bzglpowerPoints, modelpower));
            //日---最优/保证
            cfmday.setDeviationRate3(pcl(windMap.get(key).getRzyglPoints(), bzglpowerPoints, modelpower));
            //日---实际/上日实际
            cfmday.setMonthDeviationRate(pcl(windMap.get(key).getRsjglPoints(), dayLastMonthPoints, modelpower));
            //日---实际/同期实际
            cfmday.setYearDeviationRate(pcl(windMap.get(key).getRsjglPoints(), dayLastYearPoints, modelpower));
            //日---实际/标杆实际
            cfmday.setStandardDeviationRate(pcl(windMap.get(key).getRsjglPoints(), dayStandardPoints, modelpower));

            mainls.add(cfmday);
            //proEconCurveFittingMainService.save(cfmday);
            //*********************************************当日曲线偏差记录**********************************************************/
            List<ProEconCurveFittingSub> subls = new ArrayList<>();
            subls.add(pLCBuild(key, recordDate, windMap, modelpower, 3, bzglpowerPoints, dayLastMonthPoints, dayLastYearPoints, dayStandardPoints));
            subls.add(pLCBuild(key, recordDate, windMap, modelpower, 4, bzglpowerPoints, dayLastMonthPoints, dayLastYearPoints, dayStandardPoints));
            subls.add(pLCBuild(key, recordDate, windMap, modelpower, 5, bzglpowerPoints, dayLastMonthPoints, dayLastYearPoints, dayStandardPoints));
            subls.add(pLCBuild(key, recordDate, windMap, modelpower, 6, bzglpowerPoints, dayLastMonthPoints, dayLastYearPoints, dayStandardPoints));
            subls.add(pLCBuild(key, recordDate, windMap, modelpower, 7, bzglpowerPoints, dayLastMonthPoints, dayLastYearPoints, dayStandardPoints));
            subls.add(pLCBuild(key, recordDate, windMap, modelpower, 8, bzglpowerPoints, dayLastMonthPoints, dayLastYearPoints, dayStandardPoints));
            subls.add(pLCBuild(key, recordDate, windMap, modelpower, 9, bzglpowerPoints, dayLastMonthPoints, dayLastYearPoints, dayStandardPoints));
            subls.add(pLCBuild(key, recordDate, windMap, modelpower, 10, bzglpowerPoints, dayLastMonthPoints, dayLastYearPoints, dayStandardPoints));
            subls.add(pLCBuild(key, recordDate, windMap, modelpower, 11, bzglpowerPoints, dayLastMonthPoints, dayLastYearPoints, dayStandardPoints));
            subls.add(pLCBuild(key, recordDate, windMap, modelpower, 12, bzglpowerPoints, dayLastMonthPoints, dayLastYearPoints, dayStandardPoints));
            subls.add(pLCBuild(key, recordDate, windMap, modelpower, 13, bzglpowerPoints, dayLastMonthPoints, dayLastYearPoints, dayStandardPoints));


            List<ProEconCurveFittingSub> templs = new ArrayList<>();
            for (ProEconCurveFittingSub vo : subls) {
                templs.add(vo);
                if (templs.size() == 1000) {
                    proEconCurveFittingSubService.saveOrUpdateBatch(templs);
                    templs = new ArrayList<>();
                }
            }

            if (!templs.isEmpty()) {
                proEconCurveFittingSubService.saveOrUpdateBatch(templs);
            }
            //            proEconCurveFittingSubService.saveBatch(subls);

            insertPoints(recordDate, windMap.get(key).getRsjglPoints(), windMap.get(key).getRzyglPoints(), key);

            logger.info(key);
            //
            //            logger.info(String.format("{1}:更新sqlserver数据库记录数：{0}", z, new Date()));


        }


        List<ProEconCurveFittingMain> templs = new ArrayList<>();
        for (ProEconCurveFittingMain vo : mainls) {
            templs.add(vo);
            if (templs.size() == 1000) {
                proEconCurveFittingMainService.saveOrUpdateBatch(templs);
                templs = new ArrayList<>();
            }
        }

        if (!templs.isEmpty()) {
            proEconCurveFittingMainService.saveOrUpdateBatch(templs);
        }
        //        proEconCurveFittingMainService.saveBatch(mainls);
    }

    public void cureFittingMonth(Date recordDate, String type) throws Exception {
        //日期变为昨天
        Date end = DateUtils.addDays(DateUtils.truncate(recordDate), -1);

        Calendar c = Calendar.getInstance();
        c.setTime(recordDate);
        int day_year = c.get(Calendar.YEAR);
        int day_month = c.get(Calendar.MONTH) + 1;


        proEconWtCurveFittingMonthService.deleteProEconWtCurveFittingGByMonth(String.valueOf(day_year), String.valueOf(day_month));
        proEconCurveFittMonthMainService.deleteProEconCurveFittMonthMainGByMonth(String.valueOf(day_year), String.valueOf(day_month));
        proEconCurveFittMonthSubService.deleteProEconCurveFittMonthSubGByMonth(String.valueOf(day_year), String.valueOf(day_month));
        c.set(Calendar.DAY_OF_MONTH, 1);
        Date begin = c.getTime();

        //上个月
        c.setTime(DateUtils.addMonths(begin, -1));
        int month_year = c.get(Calendar.YEAR);
        int month_month = c.get(Calendar.MONTH) + 1;

        //去年同期
        c.setTime(DateUtils.addYears(begin, -1));
        int year_year = c.get(Calendar.YEAR);
        int year_month = c.get(Calendar.MONTH) + 1;

        Map<String, CureFittingVo> windMap = new HashMap<>();

        if (windturbineCapacity == null) {
            windturbineCapacity = new HashMap<>();
            Map<String, ProEconEquipmentmodel> modelMap = CacheContext.modelMap;
            for (ProBasicEquipment windturbine : CacheContext.wtls) {
                if (modelMap.containsKey(windturbine.getModelId())) {
                    windturbineCapacity.put(windturbine.getId(), modelMap.get(windturbine.getModelId()).getPowerProduction());
                }
            }
        }

        for (ProBasicEquipment wt : CacheContext.wtls) {
            String windturbineId = wt.getId();

            if (wt.getWindpowerstationId().contains(WpType.GDC.id)) {
                continue;
            }
            Map<String, ProBasicEquipmentPoint> windturbinetestingpointnewMap = CacheContext.wtpAimap.get(wt.getId());
            //设备有功功率
            String pointIdGL = windturbinetestingpointnewMap.get(ContantXk.CJ_SSGL).getNemCode();
            //设备明细状态
            String pointIdZT = windturbinetestingpointnewMap.get(ContantXk.MXZT).getNemCode();

            String pointIdFS;
            if (wt.getWindpowerstationId().contains(WpType.GDC.id)) {   //测风塔70米风速

                if (windturbinetestingpointnewMap.containsKey(ContantXk.FCCFTFS70)) {
                    ProBasicEquipmentPoint point = windturbinetestingpointnewMap.get(ContantXk.FCCFTFS70);

                    if (StringUtils.notEmp(point.getNemCode()) && !point.getNemCode().equals(initialcode)) {
                        pointIdFS = windturbinetestingpointnewMap.get(ContantXk.FCCFTFS70).getNemCode();
                    } else {
                        pointIdFS = windturbinetestingpointnewMap.get(ContantXk.CJ_SSFS).getNemCode();
                    }
                } else {
                    pointIdFS = windturbinetestingpointnewMap.get(ContantXk.CJ_SSFS).getNemCode();
                }


            } else {   //设备风速
                pointIdFS = windturbinetestingpointnewMap.get(ContantXk.CJ_SSFS).getNemCode();
            }


            CureFittingVo item = new CureFittingVo();

            item.setPointIdFS(pointIdFS);
            item.setPointIdZT(pointIdZT);
            item.setPointIdGL(pointIdGL);

            //获取标杆风机编号
            if (CacheContext.wtstandardmap.containsKey(wt.getId())) {
                item.setStandardId(CacheContext.wtstandardmap.get(wt.getId()));
            } else {
                item.setStandardId(wt.getId());
            }

            windMap.put(windturbineId, item);
        }

        for (String key : windMap.keySet()) {
            //初始化集合
            windMap.get(key).setYsjglPoints(new ArrayList<>());
            windMap.get(key).setYzyglPoints(new ArrayList<>());
            windMap.get(key).setRsjglPoints(new ArrayList<>());
            windMap.get(key).setRzyglPoints(new ArrayList<>());
            windMap.get(key).setNsjglPoints(new ArrayList<>());
            windMap.get(key).setNzyglPoints(new ArrayList<>());

            if (windMap.get(key).getPointIdGL() == null || windMap.get(key).getPointIdFS() == null || windMap.get(key).getPointIdZT() == null) {
                logger.info(key);
                continue;
            }

            //拟合月功率曲线
            curveFittingBuilder(begin, end, dimension, scale, windMap.get(key).getPointIdGL(), windMap.get(key).getPointIdFS(), windMap.get(key).getPointIdZT(), windMap.get(key).getYsjglPoints(), windMap.get(key).getYzyglPoints(), key);

            List<PointVo> vos = windMap.get(key).getYsjglPoints().stream().filter(it -> it.getX() >= 0 && it.getX() <= 1000).sorted(Comparator.comparing(PointVo::getX)).collect(Collectors.toList());
            windMap.get(key).setYsjglPoints(vos);
            vos = windMap.get(key).getYzyglPoints().stream().filter(it -> it.getX() >= 0 && it.getX() <= 1000).sorted(Comparator.comparing(PointVo::getX)).collect(Collectors.toList());
            windMap.get(key).setYzyglPoints(vos);

            logger.info(key + "曲线拟合完成！");
        }
        logger.info("曲线拟合完成！");
        List<ProEconCurveFittMonthMain> mainls = new ArrayList<>();
        for (String key : windMap.keySet()) {

            Double modelpower = 1500.0;
            if (windturbineCapacity.containsKey(key)) {
                modelpower = windturbineCapacity.get(key);
            }


            //月的上月
            List<PointVo> monthLastMonthPoints = new ArrayList<>();
            //月的去年同期
            List<PointVo> monthLastYearPoints = new ArrayList<>();
            //月标准功率
            List<PointVo> monthStandardPoints = new ArrayList<>();


            //保证功率
            List<PointVo> bzglpowerPoints = new ArrayList<>();


            if (CacheContext.wtstandardmap.containsKey(key)) {
                String standardId = CacheContext.wtstandardmap.get(key);
                if (StringUtils.notEmp(standardId)) {
                    if (windMap.containsKey(key)) {

                        monthStandardPoints = windMap.get(standardId).getYsjglPoints();

                    }
                }
            }
            String stringyear = String.valueOf(day_year);
            String stringmonth = String.valueOf(day_month);

            String stringyear2 = String.valueOf(month_year);
            String stringmonth2 = String.valueOf(month_month);

            String stringyear3 = String.valueOf(year_year);
            String stringmonth3 = String.valueOf(year_month);


            //*********************************************月曲线偏差上个月和上一年记录**********************************************************/
            QueryWrapper<ProEconWtCurveFittingMonth> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("year", stringyear2).eq("month", stringmonth2).eq("windturbine_id", key);
            List<ProEconWtCurveFittingMonth> wcfmls = proEconWtCurveFittingMonthService.list(queryWrapper).stream()
                    //                    .filter(i -> i.getWindturbineId().equals(key) &&
                    //                    i.getYear().equals(stringyear2) && i.getMonth().equals(stringmonth2))
                    .sorted(Comparator.comparing(ProEconWtCurveFittingMonth::getSpeed)).collect(Collectors.toList());

            monthBuildPoints(wcfmls, monthLastMonthPoints);
            QueryWrapper<ProEconWtCurveFittingMonth> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.eq("year", stringyear3).eq("month", stringmonth3).eq("windturbine_id", key);
            wcfmls = proEconWtCurveFittingMonthService.list(queryWrapper2).stream()
                    //                    .filter(i -> i.getWindturbineId().equals(key) &&
                    //                    i.getYear().equals(stringyear3) && i.getMonth().equals(stringmonth3))
                    .sorted(Comparator.comparing(ProEconWtCurveFittingMonth::getSpeed)).collect(Collectors.toList());

            monthBuildPoints(wcfmls, monthLastYearPoints);
            //*********************************************月曲线偏差上个月和上一年记录**********************************************************/

            if (CacheContext.wtmap.containsKey(key)) {
                String modelid = CacheContext.wtmap.get(key).getModelId();
                if (StringUtils.notEmp(modelid)) {
                    //获取模型功率曲线
                    if (CacheContext.theoreticalPowerMap.containsKey(modelid)) {
                        for (Double speed : CacheContext.theoreticalPowerMap.get(modelid).keySet()) {
                            PointVo point = new PointVo();
                            point.setX(speed);
                            point.setY(CacheContext.theoreticalPowerMap.get(modelid).get(speed).getEnsurePower());

                            bzglpowerPoints.add(point);
                        }
                    }
                }
            }

            //*********************************************年曲线偏差记录**********************************************************/


            //*********************************************当月曲线偏差记录**********************************************************/
            QueryWrapper<ProEconCurveFittMonthMain> queryWrapper3 = new QueryWrapper<>();
            queryWrapper3.eq("year", stringyear).eq("month", stringmonth).eq("windturbine_id", key);
            Optional<ProEconCurveFittMonthMain> cfmmontho = proEconCurveFittMonthMainService.list(queryWrapper3).stream()
                    //                    .filter(i -> i.getWindturbineId().equals(key)
                    //                    && i.getYear().equals(stringyear) && i.getMonth().equals(stringmonth))
                    .findFirst();
            ProEconCurveFittMonthMain cfmmonth;
            if (cfmmontho.isPresent()) {
                cfmmonth = cfmmontho.get();

                QueryWrapper<ProEconCurveFittMonthMain> wrapper = new QueryWrapper<>();
                wrapper.eq("id", cfmmonth.getId());
                proEconCurveFittMonthMainService.remove(wrapper);
            }


            cfmmonth = new ProEconCurveFittMonthMain();
            cfmmonth.setWindturbineId(key);
            cfmmonth.setYear(String.valueOf(day_year));
            cfmmonth.setMonth(String.valueOf(day_month));

            //月---实际/最优
            cfmmonth.setDeviationRate1(pcl(windMap.get(key).getYsjglPoints(), windMap.get(key).getYzyglPoints(), modelpower));
            //月---实际/保证
            cfmmonth.setDeviationRate2(pcl(windMap.get(key).getYsjglPoints(), bzglpowerPoints, modelpower));
            //月---最优/保证
            cfmmonth.setDeviationRate3(pcl(windMap.get(key).getYzyglPoints(), bzglpowerPoints, modelpower));
            //月---实际/上月实际
            cfmmonth.setMonthDeviationRate(pcl(windMap.get(key).getYsjglPoints(), monthLastMonthPoints, modelpower));
            //月---实际/同期实际
            cfmmonth.setYearDeviationRate(pcl(windMap.get(key).getYsjglPoints(), monthLastYearPoints, modelpower));
            //月---实际/标杆实际
            cfmmonth.setStandardDeviationRate(pcl(windMap.get(key).getYsjglPoints(), monthStandardPoints, modelpower));

            mainls.add(cfmmonth);
            // proEconCurveFittMonthMainService.save(cfmmonth);

            //*********************************************当月曲线偏差记录**********************************************************/
            List<ProEconCurveFittMonthSub> subls = new ArrayList<>();
            subls.add(pLCBuild(key, stringyear, stringmonth, windMap, modelpower, 3, bzglpowerPoints, monthLastMonthPoints, monthLastYearPoints, monthStandardPoints));
            subls.add(pLCBuild(key, stringyear, stringmonth, windMap, modelpower, 4, bzglpowerPoints, monthLastMonthPoints, monthLastYearPoints, monthStandardPoints));
            subls.add(pLCBuild(key, stringyear, stringmonth, windMap, modelpower, 5, bzglpowerPoints, monthLastMonthPoints, monthLastYearPoints, monthStandardPoints));
            subls.add(pLCBuild(key, stringyear, stringmonth, windMap, modelpower, 6, bzglpowerPoints, monthLastMonthPoints, monthLastYearPoints, monthStandardPoints));
            subls.add(pLCBuild(key, stringyear, stringmonth, windMap, modelpower, 7, bzglpowerPoints, monthLastMonthPoints, monthLastYearPoints, monthStandardPoints));
            subls.add(pLCBuild(key, stringyear, stringmonth, windMap, modelpower, 8, bzglpowerPoints, monthLastMonthPoints, monthLastYearPoints, monthStandardPoints));
            subls.add(pLCBuild(key, stringyear, stringmonth, windMap, modelpower, 9, bzglpowerPoints, monthLastMonthPoints, monthLastYearPoints, monthStandardPoints));
            subls.add(pLCBuild(key, stringyear, stringmonth, windMap, modelpower, 10, bzglpowerPoints, monthLastMonthPoints, monthLastYearPoints, monthStandardPoints));
            subls.add(pLCBuild(key, stringyear, stringmonth, windMap, modelpower, 11, bzglpowerPoints, monthLastMonthPoints, monthLastYearPoints, monthStandardPoints));
            subls.add(pLCBuild(key, stringyear, stringmonth, windMap, modelpower, 12, bzglpowerPoints, monthLastMonthPoints, monthLastYearPoints, monthStandardPoints));
            subls.add(pLCBuild(key, stringyear, stringmonth, windMap, modelpower, 13, bzglpowerPoints, monthLastMonthPoints, monthLastYearPoints, monthStandardPoints));

            List<ProEconCurveFittMonthSub> templs = new ArrayList<>();
            for (ProEconCurveFittMonthSub vo : subls) {
                templs.add(vo);
                if (templs.size() == 1000) {
                    proEconCurveFittMonthSubService.saveOrUpdateBatch(templs);
                    templs = new ArrayList<>();
                }
            }

            if (!templs.isEmpty()) {
                proEconCurveFittMonthSubService.saveOrUpdateBatch(templs);
            }
            //            proEconCurveFittMonthSubService.saveBatch(subls);
            insertPoints(stringyear, stringmonth, windMap.get(key).getYsjglPoints(), windMap.get(key).getYzyglPoints(), key);

            if (type.equals("1")) {
                insertPoints2(windMap.get(key).getYsjglPoints(), windMap.get(key).getYzyglPoints(), key);
            }

            logger.info(key + "月曲线偏差率完成！");
            //            logger.info(String.format("{1}:更新sqlserver数据库记录数：{0}", z, new Date()));


        }

        List<ProEconCurveFittMonthMain> templs = new ArrayList<>();
        for (ProEconCurveFittMonthMain vo : mainls) {
            templs.add(vo);
            if (templs.size() == 1000) {
                proEconCurveFittMonthMainService.saveOrUpdateBatch(templs);
                templs = new ArrayList<>();
            }
        }

        if (!templs.isEmpty()) {
            proEconCurveFittMonthMainService.saveOrUpdateBatch(templs);
        }
        //        proEconCurveFittMonthMainService.saveBatch(mainls);

        logger.info("曲线保存完成！");
    }


    public void cureFittingYear(Date recordDate) throws Exception {
        //日期变为昨天
        Date end = DateUtils.addDays(DateUtils.truncate(recordDate), -1);

        Calendar c = Calendar.getInstance();

        c.setTime(recordDate);
        int day_year = c.get(Calendar.YEAR);


        proEconWtCurveFittingYearService.deleteProEconWtCurveFittingGByYear(String.valueOf(day_year));
        proEconCurveFittYearMainService.deleteProEconCurveFittYearMainGByYear(String.valueOf(day_year));
        proEconCurveFittYearSubService.deleteProEconCurveFittYearSubGByYear(String.valueOf(day_year));
        c.set(Calendar.DAY_OF_MONTH, 1);
        c.set(Calendar.MONTH, 0);
        Date begin = c.getTime();


        //去年同期
        c.setTime(DateUtils.addYears(begin, -1));
        int year_year = c.get(Calendar.YEAR);


        Map<String, CureFittingVo> windMap = new HashMap<>();

        if (windturbineCapacity == null) {
            windturbineCapacity = new HashMap<>();
            Map<String, ProEconEquipmentmodel> modelMap = CacheContext.modelMap;
            for (ProBasicEquipment windturbine : CacheContext.wtls) {
                if (modelMap.containsKey(windturbine.getModelId())) {
                    windturbineCapacity.put(windturbine.getId(), modelMap.get(windturbine.getModelId()).getPowerProduction());
                }
            }
        }

        for (ProBasicEquipment wt : CacheContext.wtls) {
            String windturbineId = wt.getId();

            if (wt.getWindpowerstationId().contains(WpType.GDC.id)) {
                continue;
            }
            Map<String, ProBasicEquipmentPoint> windturbinetestingpointnewMap = CacheContext.wtpAimap.get(wt.getId());
            //设备有功功率
            String pointIdGL = windturbinetestingpointnewMap.get(ContantXk.CJ_SSGL).getNemCode();
            //设备明细状态
            String pointIdZT = windturbinetestingpointnewMap.get(ContantXk.MXZT).getNemCode();

            String pointIdFS;
            if (wt.getWindpowerstationId().contains(WpType.GDC.id)) {   //测风塔70米风速

                if (windturbinetestingpointnewMap.containsKey(ContantXk.FCCFTFS70)) {
                    ProBasicEquipmentPoint point = windturbinetestingpointnewMap.get(ContantXk.FCCFTFS70);

                    if (StringUtils.notEmp(point.getNemCode()) && !point.getNemCode().equals(initialcode)) {
                        pointIdFS = windturbinetestingpointnewMap.get(ContantXk.FCCFTFS70).getNemCode();
                    } else {
                        pointIdFS = windturbinetestingpointnewMap.get(ContantXk.CJ_SSFS).getNemCode();
                    }
                } else {
                    pointIdFS = windturbinetestingpointnewMap.get(ContantXk.CJ_SSFS).getNemCode();
                }


            } else {   //设备风速
                pointIdFS = windturbinetestingpointnewMap.get(ContantXk.CJ_SSFS).getNemCode();
            }


            CureFittingVo item = new CureFittingVo();

            item.setPointIdFS(pointIdFS);
            item.setPointIdZT(pointIdZT);
            item.setPointIdGL(pointIdGL);

            //获取标杆风机编号
            if (CacheContext.wtstandardmap.containsKey(wt.getId())) {
                item.setStandardId(CacheContext.wtstandardmap.get(wt.getId()));
            } else {
                item.setStandardId(wt.getId());
            }

            windMap.put(windturbineId, item);
        }

        for (String key : windMap.keySet()) {
            //初始化集合
            windMap.get(key).setYsjglPoints(new ArrayList<>());
            windMap.get(key).setYzyglPoints(new ArrayList<>());
            windMap.get(key).setRsjglPoints(new ArrayList<>());
            windMap.get(key).setRzyglPoints(new ArrayList<>());
            windMap.get(key).setNsjglPoints(new ArrayList<>());
            windMap.get(key).setNzyglPoints(new ArrayList<>());

            //            if (windMap.get(key).getPointIdGL() == null || windMap.get(key).getPointIdFS() == null || windMap.get(key).getPointIdZT() == null) {
            //                logger.info(key);
            //                continue;
            //            }


            //拟合年功率曲线
            //  curveFittingBuilder(begin, end, dimension, scale, windMap.get(key).getPointIdGL(), windMap.get(key).getPointIdFS(), windMap.get(key).getPointIdZT(), windMap.get(key).getNsjglPoints(), windMap.get(key).getNzyglPoints(), key);
            QueryWrapper<ProEconWtPowerCurveFitting> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("windturbine_id", key);
            List<ProEconWtPowerCurveFitting> wtpowerls = proEconWtPowerCurveFittingService.list(queryWrapper)
                    .stream()
                    //                    .filter(i->i.getWindturbineId().equals(key))
                    .sorted(Comparator.comparing(ProEconWtPowerCurveFitting::getSpeed)).collect(Collectors.toList());

            List<PointVo> zyglls = new ArrayList<>();
            List<PointVo> sjglls = new ArrayList<>();
            if (!wtpowerls.isEmpty()) {

                for (ProEconWtPowerCurveFitting wtp : wtpowerls) {
                    PointVo zyvo = new PointVo();
                    zyvo.setX(wtp.getSpeed());
                    zyvo.setY(wtp.getOptimalPower());
                    zyglls.add(zyvo);

                    PointVo sjvo = new PointVo();
                    sjvo.setX(wtp.getSpeed());
                    sjvo.setY(wtp.getActualPower());
                    sjglls.add(sjvo);
                }
            }
            //            List<PointVo> vos = windMap.get(key).getNsjglPoints().stream().filter(it -> it.getX() >= 0 && it.getX() <= 1000).sorted(Comparator.comparing(PointVo::getX)).collect(Collectors.toList());
            //            windMap.get(key).setNsjglPoints(vos);
            //            vos = windMap.get(key).getNzyglPoints().stream().filter(it -> it.getX() >= 0 && it.getX() <= 1000).sorted(Comparator.comparing(PointVo::getX)).collect(Collectors.toList());
            //            windMap.get(key).setNzyglPoints(vos);


            windMap.get(key).setNsjglPoints(sjglls);
            windMap.get(key).setNzyglPoints(zyglls);
        }

        List<ProEconCurveFittYearMain> mainls = new ArrayList<>();
        for (String key : windMap.keySet()) {

            Double modelpower = 1500.0;
            if (windturbineCapacity.containsKey(key)) {
                modelpower = windturbineCapacity.get(key);
            }

            //年的上月
            List<PointVo> yearLastMonthPoints = new ArrayList<>();
            //年的去年同期
            List<PointVo> yearLastYearPoints;
            //年标准功率
            List<PointVo> yearStandardPoints = new ArrayList<>();


            //日的昨天

            //保证功率
            List<PointVo> bzglpowerPoints = new ArrayList<>();


            if (CacheContext.wtstandardmap.containsKey(key)) {
                String standardId = CacheContext.wtstandardmap.get(key);
                if (StringUtils.notEmp(standardId)) {
                    if (windMap.containsKey(key)) {
                        yearStandardPoints = windMap.get(standardId).getNsjglPoints();

                    }
                }
            }

            String stringyear = String.valueOf(day_year);


            String stringyear3 = String.valueOf(year_year);


            // /*********************************************年曲线偏差上个月和上一年记录**********************************************************/

            QueryWrapper<ProEconWtCurveFittingYear> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("year", stringyear3).eq("windturbine_id", key);
            List<ProEconWtCurveFittingYear> wcfyls = proEconWtCurveFittingYearService.list(queryWrapper).stream()
                    //                    .filter(i -> i.getWindturbineId().equals(key) &&
                    //                    i.getYear().equals(stringyear3))
                    .sorted(Comparator.comparing(ProEconWtCurveFittingYear::getSpeed)).collect(Collectors.toList());

            //与轶总的原始代码对比不一致，新增代码修改测试
            yearBuildPoints(wcfyls, yearLastMonthPoints);
            yearLastYearPoints = yearLastMonthPoints;

            //*********************************************年曲线偏差上个月和上一年记录**********************************************************/

            if (CacheContext.wtmap.containsKey(key)) {
                String modelid = CacheContext.wtmap.get(key).getModelId();
                if (StringUtils.notEmp(modelid)) {
                    //获取模型功率曲线
                    if (CacheContext.theoreticalPowerMap.containsKey(modelid)) {
                        for (Double speed : CacheContext.theoreticalPowerMap.get(modelid).keySet()) {
                            PointVo point = new PointVo();
                            point.setX(speed);
                            point.setY(CacheContext.theoreticalPowerMap.get(modelid).get(speed).getEnsurePower());

                            bzglpowerPoints.add(point);
                        }
                    }
                }
            }
            //*********************************************年曲线偏差记录**********************************************************/

            //*********************************************当年曲线偏差记录**********************************************************/
            QueryWrapper<ProEconCurveFittYearMain> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.eq("year", stringyear).eq("windturbine_id", key);
            Optional<ProEconCurveFittYearMain> cfmyearo = proEconCurveFittYearMainService.list(queryWrapper2)
                    .stream()
                    //                    .filter(i -> i.getWindturbineId().equals(key)
                    //                    && i.getYear().equals(stringyear))
                    .findFirst();
            ProEconCurveFittYearMain cfmyear;
            if (cfmyearo.isPresent()) {
                cfmyear = cfmyearo.get();

                QueryWrapper<ProEconCurveFittMonthMain> wrapper = new QueryWrapper<>();
                wrapper.eq("id", cfmyear.getId());
                proEconCurveFittMonthMainService.remove(wrapper);
            }


            cfmyear = new ProEconCurveFittYearMain();
            cfmyear.setWindturbineId(key);
            cfmyear.setYear(String.valueOf(day_year));


            //年---实际/最优
            cfmyear.setDeviationRate1(pcl(windMap.get(key).getNsjglPoints(), windMap.get(key).getNzyglPoints(), modelpower));
            //年---实际/保证
            cfmyear.setDeviationRate2(pcl(windMap.get(key).getNsjglPoints(), bzglpowerPoints, modelpower));
            //年---最优/保证
            cfmyear.setDeviationRate3(pcl(windMap.get(key).getNzyglPoints(), bzglpowerPoints, modelpower));
            //年---实际/上月实际
            cfmyear.setMonthDeviationRate(pcl(windMap.get(key).getNsjglPoints(), yearLastMonthPoints, modelpower));
            //年---实际/同期实际
            cfmyear.setYearDeviationRate(pcl(windMap.get(key).getNsjglPoints(), yearLastYearPoints, modelpower));
            //年---实际/标杆实际
            cfmyear.setStandardDeviationRate(pcl(windMap.get(key).getNsjglPoints(), yearStandardPoints, modelpower));

            mainls.add(cfmyear);
            // proEconCurveFittYearMainService.save(cfmyear);

            //*********************************************当年曲线偏差记录**********************************************************/
            List<ProEconCurveFittYearSub> subls = new ArrayList<>();
            subls.add(pLCBuild(key, stringyear, windMap, modelpower, 3, bzglpowerPoints, yearLastMonthPoints, yearLastYearPoints, yearStandardPoints));
            subls.add(pLCBuild(key, stringyear, windMap, modelpower, 4, bzglpowerPoints, yearLastMonthPoints, yearLastYearPoints, yearStandardPoints));
            subls.add(pLCBuild(key, stringyear, windMap, modelpower, 5, bzglpowerPoints, yearLastMonthPoints, yearLastYearPoints, yearStandardPoints));
            subls.add(pLCBuild(key, stringyear, windMap, modelpower, 6, bzglpowerPoints, yearLastMonthPoints, yearLastYearPoints, yearStandardPoints));
            subls.add(pLCBuild(key, stringyear, windMap, modelpower, 7, bzglpowerPoints, yearLastMonthPoints, yearLastYearPoints, yearStandardPoints));
            subls.add(pLCBuild(key, stringyear, windMap, modelpower, 8, bzglpowerPoints, yearLastMonthPoints, yearLastYearPoints, yearStandardPoints));
            subls.add(pLCBuild(key, stringyear, windMap, modelpower, 9, bzglpowerPoints, yearLastMonthPoints, yearLastYearPoints, yearStandardPoints));
            subls.add(pLCBuild(key, stringyear, windMap, modelpower, 10, bzglpowerPoints, yearLastMonthPoints, yearLastYearPoints, yearStandardPoints));
            subls.add(pLCBuild(key, stringyear, windMap, modelpower, 11, bzglpowerPoints, yearLastMonthPoints, yearLastYearPoints, yearStandardPoints));
            subls.add(pLCBuild(key, stringyear, windMap, modelpower, 12, bzglpowerPoints, yearLastMonthPoints, yearLastYearPoints, yearStandardPoints));
            subls.add(pLCBuild(key, stringyear, windMap, modelpower, 13, bzglpowerPoints, yearLastMonthPoints, yearLastYearPoints, yearStandardPoints));


            List<ProEconCurveFittYearSub> templs = new ArrayList<>();
            for (ProEconCurveFittYearSub vo : subls) {
                templs.add(vo);
                if (templs.size() == 1000) {
                    proEconCurveFittYearSubService.saveOrUpdateBatch(templs);
                    templs = new ArrayList<>();
                }
            }

            if (!templs.isEmpty()) {
                proEconCurveFittYearSubService.saveOrUpdateBatch(templs);
            }

            //            proEconCurveFittYearSubService.saveBatch(subls);
            insertPoints(stringyear, windMap.get(key).getNsjglPoints(), windMap.get(key).getNzyglPoints(), key);

            logger.info(key);
            //
            //            logger.info(String.format("{1}:更新sqlserver数据库记录数：{0}", z, new Date()));


        }

        List<ProEconCurveFittYearMain> templs = new ArrayList<>();
        for (ProEconCurveFittYearMain vo : mainls) {
            templs.add(vo);
            if (templs.size() == 1000) {
                proEconCurveFittYearMainService.saveOrUpdateBatch(templs);
                templs = new ArrayList<>();
            }
        }

        if (!templs.isEmpty()) {
            proEconCurveFittYearMainService.saveOrUpdateBatch(templs);
        }

        //        proEconCurveFittYearMainService.saveBatch(mainls);
    }


    public ProEconCurveFittingSub pLCBuild(String key, Date current, Map<String, CureFittingVo> windMap, Double modelpower, double speed,
                                           List<PointVo> bzglpowerPoints, List<PointVo> lastMonthPoints, List<PointVo> lastYearPoints, List<PointVo> lastStandardPoints
    ) {

        //        String speedStr = String.valueOf(speed);

        //*********************************************当日曲线偏差子表记录**********************************************************/
        QueryWrapper<ProEconCurveFittingSub> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("record_date", current).eq("speed", speed).eq("windturbine_id", key);
        Optional<ProEconCurveFittingSub> cfmso = proEconCurveFittingSubService.list(queryWrapper2)
                .stream()
                //                .filter(i -> i.getWindturbineId().equals(key)
                //                && i.getRecordDate().compareTo(current) == 0 && i.getSpeed().equals(speedStr))
                .findFirst();
        ProEconCurveFittingSub cfms;

        if (cfmso.isPresent()) {
            cfms = cfmso.get();

            QueryWrapper<ProEconCurveFittingSub> wrapper = new QueryWrapper<>();
            wrapper.eq("id", cfms.getId());
            proEconCurveFittingSubService.remove(wrapper);
        }

        cfms = new ProEconCurveFittingSub();
        cfms.setWindturbineId(key);
        cfms.setSpeed(speed);
        cfms.setRecordDate(DateUtils.truncate(current));


        cfms.setDeviationRate1(pcl2(windMap.get(key).getRsjglPoints(), windMap.get(key).getRzyglPoints(), modelpower, speed));
        //日---实际/保证
        cfms.setDeviationRate2(pcl2(windMap.get(key).getRsjglPoints(), bzglpowerPoints, modelpower, speed));
        //日---最优/保证
        cfms.setDeviationRate3(pcl2(windMap.get(key).getRzyglPoints(), bzglpowerPoints, modelpower, speed));
        //日---实际/上日实际
        cfms.setMonthDeviationRate(pcl2(windMap.get(key).getRsjglPoints(), lastMonthPoints, modelpower, speed));
        //日---实际/同期实际
        cfms.setYearDeviationRate(pcl2(windMap.get(key).getRsjglPoints(), lastYearPoints, modelpower, speed));
        //日---实际/标杆实际
        cfms.setStandardDeviationRate(pcl2(windMap.get(key).getRsjglPoints(), lastStandardPoints, modelpower, speed));

        return cfms;

        //proEconCurveFittingSubService.save(cfms);
        //*********************************************当日曲线偏差子表记录**********************************************************/
    }

    public ProEconCurveFittMonthSub pLCBuild(String key, String stringyear, String stringmonth, Map<String, CureFittingVo> windMap, Double modelpower, double speed,
                                             List<PointVo> bzglpowerPoints, List<PointVo> lastMonthPoints, List<PointVo> lastYearPoints, List<PointVo> lastStandardPoints
    ) {
        //        String speedStr = String.valueOf(speed);

        //*********************************************当月曲线偏差子表记录**********************************************************/
        QueryWrapper<ProEconCurveFittMonthSub> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("year", stringyear).eq("month", stringmonth).eq("speed", speed).eq("windturbine_id", key);
        Optional<ProEconCurveFittMonthSub> cfmsmontho = proEconCurveFittMonthSubService.list(queryWrapper2).stream()
                //                .filter(i -> i.getWindturbineId().equals(key)
                //                && i.getYear().equals(stringyear) && i.getMonth().equals(stringmonth) && i.getSpeed().equals(speedStr))
                .findFirst();
        ProEconCurveFittMonthSub cfmsmonth;

        if (cfmsmontho.isPresent()) {
            cfmsmonth = cfmsmontho.get();

            QueryWrapper<ProEconCurveFittMonthSub> wrapper = new QueryWrapper<>();
            wrapper.eq("id", cfmsmonth.getId());
            proEconCurveFittMonthSubService.remove(wrapper);
        }

        cfmsmonth = new ProEconCurveFittMonthSub();

        cfmsmonth.setWindturbineId(key);
        cfmsmonth.setYear(stringyear);
        cfmsmonth.setMonth(stringmonth);
        cfmsmonth.setSpeed(speed);


        //月---实际/最优
        cfmsmonth.setDeviationRate1(pcl2(windMap.get(key).getYsjglPoints(), windMap.get(key).getYzyglPoints(), modelpower, speed));
        //月---实际/保证
        cfmsmonth.setDeviationRate2(pcl2(windMap.get(key).getYsjglPoints(), bzglpowerPoints, modelpower, speed));
        //月---最优/保证
        cfmsmonth.setDeviationRate3(pcl2(windMap.get(key).getYzyglPoints(), bzglpowerPoints, modelpower, speed));
        //月---实际/上月实际
        cfmsmonth.setMonthDeviationRate(pcl2(windMap.get(key).getYsjglPoints(), lastMonthPoints, modelpower, speed));
        //月---实际/同期实际
        cfmsmonth.setYearDeviationRate(pcl2(windMap.get(key).getYsjglPoints(), lastYearPoints, modelpower, speed));
        //月---实际/标杆实际
        cfmsmonth.setStandardDeviationRate(pcl2(windMap.get(key).getYsjglPoints(), lastStandardPoints, modelpower, speed));

        //        proEconCurveFittMonthSubService.save(cfmsmonth);

        return cfmsmonth;
        //*********************************************当月曲线偏差子表记录**********************************************************/
    }

    public ProEconCurveFittYearSub pLCBuild(String key, String stringyear, Map<String, CureFittingVo> windMap, Double modelpower, double speed,
                                            List<PointVo> bzglpowerPoints, List<PointVo> lastMonthPoints, List<PointVo> lastYearPoints, List<PointVo> lastStandardPoints
    ) {
        //        String speedStr = String.valueOf(speed);

        //*********************************************当年曲线偏差子表记录**********************************************************/
        QueryWrapper<ProEconCurveFittYearSub> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("year", stringyear).eq("speed", speed).eq("windturbine_id", key);
        Optional<ProEconCurveFittYearSub> cfmsyearo = proEconCurveFittYearSubService.list(queryWrapper).stream()
                //                .filter(i -> i.getWindturbineId().equals(key)
                //                && i.getYear().equals(stringyear) && i.getSpeed().equals(speedStr))
                .findFirst();
        ProEconCurveFittYearSub cfmsyear;

        if (cfmsyearo.isPresent()) {
            cfmsyear = cfmsyearo.get();

            QueryWrapper<ProEconCurveFittYearSub> wrapper = new QueryWrapper<>();
            wrapper.eq("id", cfmsyear.getId());
            proEconCurveFittYearSubService.remove(wrapper);
        }

        cfmsyear = new ProEconCurveFittYearSub();
        cfmsyear.setWindturbineId(key);
        cfmsyear.setYear(stringyear);
        cfmsyear.setSpeed(speed);

        // proEconCurveFittYearSubService.save(cfmsyear);

        //年---实际/最优
        cfmsyear.setDeviationRate1(pcl2(windMap.get(key).getNsjglPoints(), windMap.get(key).getNzyglPoints(), modelpower, speed));
        //年---实际/保证
        cfmsyear.setDeviationRate2(pcl2(windMap.get(key).getNsjglPoints(), bzglpowerPoints, modelpower, speed));
        //年---最优/保证
        cfmsyear.setDeviationRate3(pcl2(windMap.get(key).getNzyglPoints(), bzglpowerPoints, modelpower, speed));
        //年---实际/上月实际
        cfmsyear.setMonthDeviationRate(pcl2(windMap.get(key).getNsjglPoints(), lastMonthPoints, modelpower, speed));
        //年---实际/同期实际
        cfmsyear.setYearDeviationRate(pcl2(windMap.get(key).getNsjglPoints(), lastYearPoints, modelpower, speed));
        //年---实际/标杆实际
        cfmsyear.setStandardDeviationRate(pcl2(windMap.get(key).getNsjglPoints(), lastStandardPoints, modelpower, speed));

        //        proEconCurveFittYearSubService.save(cfmsyear);
        return cfmsyear;
        //*********************************************当年曲线偏差子表记录**********************************************************/
    }


    private void insertPoints(Date current, List<PointVo> sjglls, List<PointVo> zyglls, String windturbineId) {

        //*********************************************当日曲线偏差记录**********************************************************/
        //        List<Long> wtcfidls = proEconWtCurveFittingService.list().stream().filter(i -> i.getWindturbineId().equals(windturbineId) &&
        //                i.getRecordDate().compareTo(current) == 0).map(ProEconWtCurveFitting::getId).collect(Collectors.toList());
        //
        //
        //        for (int i = 0; i < wtcfidls.size(); i++) {
        //            proEconWtCurveFittingService.removeByIds(wtcfidls);
        //        }

        List<ProEconWtCurveFitting> wtcfls = new ArrayList<>();
        if (sjglls.size() == zyglls.size()) {
            for (int i = 0; i < sjglls.size(); i++) {
                ProEconWtCurveFitting item = new ProEconWtCurveFitting();
                item.setWindturbineId(windturbineId);

                if (CacheContext.wtmap.containsKey(windturbineId)) {
                    ProBasicEquipment wt = CacheContext.wtmap.get(windturbineId);
                    if (wt.getWindpowerstationId().contains(WpType.GDC.id)) {
                        continue;
                        // item.SPEED = Double.Truncate(pointsF2[i].X);
                    } else {
                        //                        boolean l = String.valueOf(sjglls.get(i).getX()).contains(".");
                        //                        if (l) {
                        //                            continue;
                        //                        }
                        item.setSpeed(sjglls.get(i).getX());

                    }


                    item.setActualPower(sjglls.get(i).getY());
                    item.setOptimalPower(zyglls.get(i).getY());
                    item.setRecordDate(DateUtils.truncate(current));

                    wtcfls.add(item);
                    //proEconWtCurveFittingService.save(item);

                }

            }
        } else {
            logger.warn(String.format("下标不一致的风机编号：{0}，实际功率：{1}，最有功率：{2}", windturbineId, sjglls.size(), zyglls.size()));

            for (int i = 0; i < sjglls.size(); i++) {
                ProEconWtCurveFitting item = new ProEconWtCurveFitting();
                item.setWindturbineId(windturbineId);

                if (CacheContext.wtmap.containsKey(windturbineId)) {
                    ProBasicEquipment wt = CacheContext.wtmap.get(windturbineId);
                    if (wt.getWindpowerstationId().contains(WpType.GDC.id)) {
                        continue;
                        //item.SPEED = Double.Truncate(pointsF2[i].X);
                    } else {
                        boolean l = String.valueOf(sjglls.get(i).getX()).contains(".");
                        if (l) {
                            continue;
                        }
                        item.setSpeed(sjglls.get(i).getX());
                    }


                    int finalI = i;
                    OptionalDouble op = zyglls.stream().filter(x -> Objects.equals(x.getX(), sjglls.get(finalI).getX())).mapToDouble(PointVo::getY).findFirst();

                    if (op.isPresent()) {
                        item.setOptimalPower(op.getAsDouble());
                    } else {
                        item.setOptimalPower(0.0);
                    }

                    item.setActualPower(sjglls.get(i).getY());
                    item.setRecordDate(current);
                    wtcfls.add(item);
                    //proEconWtCurveFittingService.save(item);
                }

            }
            //*********************************************当日曲线偏差记录**********************************************************/
        }

        List<ProEconWtCurveFitting> templs = new ArrayList<>();
        for (ProEconWtCurveFitting vo : wtcfls) {
            templs.add(vo);
            if (templs.size() == 1000) {
                proEconWtCurveFittingService.saveOrUpdateBatch(templs);
                templs = new ArrayList<>();
            }
        }

        if (!templs.isEmpty()) {
            proEconWtCurveFittingService.saveOrUpdateBatch(templs);
        }
        //        proEconWtCurveFittingService.saveBatch(wtcfls);
        String s = JSONObject.toJSONString(wtcfls);
        redisService.set(CurveType.dayCurve.id + "_" + windturbineId, s);

    }


    private void insertPoints(String year, String month, List<PointVo> sjglls, List<PointVo> zyglls, String windturbineId) {

        //*********************************************当月曲线偏差记录**********************************************************/
        //        List<Long> wtcfmmonthidls = proEconWtCurveFittingMonthService.list().stream().filter(i -> i.getWindturbineId().equals(windturbineId) &&
        //                i.getYear().equals(year) && i.getMonth().equals(month)).map(ProEconWtCurveFittingMonth::getId).collect(Collectors.toList());
        //
        //
        //        for (int i = 0; i < wtcfmmonthidls.size(); i++) {
        //            proEconWtCurveFittingMonthService.removeByIds(wtcfmmonthidls);
        //        }
        List<ProEconWtCurveFittingMonth> wtcfls = new ArrayList<>();
        if (sjglls.size() == zyglls.size()) {
            for (int i = 0; i < sjglls.size(); i++) {
                ProEconWtCurveFittingMonth item = new ProEconWtCurveFittingMonth();

                item.setWindturbineId(windturbineId);
                if (CacheContext.wtmap.containsKey(windturbineId)) {
                    ProBasicEquipment wt = CacheContext.wtmap.get(windturbineId);
                    if (wt.getWindpowerstationId().contains(WpType.GDC.id)) {
                        continue;
                        // item.SPEED = Double.Truncate(pointsF1[i].X);
                    } else {
                        item.setSpeed(sjglls.get(i).getX());

                    }
                    item.setActualPower(sjglls.get(i).getY());
                    item.setOptimalPower(zyglls.get(i).getY());
                    item.setYear(String.valueOf(year));
                    item.setMonth(String.valueOf(month));
                    wtcfls.add(item);
                    // proEconWtCurveFittingMonthService.save(item);
                }

            }
        } else {
            logger.warn(String.format("下标不一致的风机编号：{0}，实际功率：{1}，最有功率：{2}", windturbineId, sjglls.size(), zyglls.size()));


            for (int i = 0; i < sjglls.size(); i++) {
                ProEconWtCurveFittingMonth item = new ProEconWtCurveFittingMonth();
                item.setWindturbineId(windturbineId);
                if (CacheContext.wtmap.containsKey(windturbineId)) {

                    ProBasicEquipment wt = CacheContext.wtmap.get(windturbineId);
                    if (wt.getWindpowerstationId().contains(WpType.GDC.id)) {
                        continue;
                        //item.SPEED = Double.Truncate(pointsF1[i].X);
                    } else {

                        item.setSpeed(sjglls.get(i).getX());
                    }
                    item.setActualPower(sjglls.get(i).getY());

                    int finalI = i;
                    OptionalDouble op = zyglls.stream().filter(x -> Objects.equals(x.getX(), sjglls.get(finalI).getX())).mapToDouble(PointVo::getY).findFirst();

                    if (op.isPresent()) {
                        item.setOptimalPower(op.getAsDouble());
                    } else {
                        item.setOptimalPower(0.0);
                    }

                    item.setYear(String.valueOf(year));
                    item.setMonth(String.valueOf(month));
                    wtcfls.add(item);
                    //proEconWtCurveFittingMonthService.save(item);
                }

            }
        }
        //*********************************************当月曲线偏差记录**********************************************************/


        List<ProEconWtCurveFittingMonth> templs = new ArrayList<>();
        for (ProEconWtCurveFittingMonth vo : wtcfls) {
            templs.add(vo);
            if (templs.size() == 1000) {
                proEconWtCurveFittingMonthService.saveOrUpdateBatch(templs);
                templs = new ArrayList<>();
            }
        }

        if (!templs.isEmpty()) {
            proEconWtCurveFittingMonthService.saveOrUpdateBatch(templs);
        }
        //        proEconWtCurveFittingMonthService.saveBatch(wtcfls);
        String s = JSONObject.toJSONString(wtcfls);
        redisService.set(CurveType.monthCurve.id + "_" + windturbineId, s);
    }

    private void insertPoints(String year, List<PointVo> sjglls, List<PointVo> zyglls, String windturbineId) {
        //*********************************************当年曲线偏差记录**********************************************************/
        //        List<Long> wtcfmyearidls = proEconWtCurveFittingYearService.list().stream().filter(i -> i.getWindturbineId().equals(windturbineId) &&
        //                i.getYear().equals(year)).map(ProEconWtCurveFittingYear::getId).collect(Collectors.toList());
        //
        //        for (int i = 0; i < wtcfmyearidls.size(); i++) {
        //            proEconWtCurveFittingYearService.removeByIds(wtcfmyearidls);
        //        }
        List<ProEconWtCurveFittingYear> wtcfls = new ArrayList<>();
        if (sjglls.size() == zyglls.size()) {
            for (int i = 0; i < sjglls.size(); i++) {
                ProEconWtCurveFittingYear item = new ProEconWtCurveFittingYear();

                item.setWindturbineId(windturbineId);
                if (CacheContext.wtmap.containsKey(windturbineId)) {
                    ProBasicEquipment wt = CacheContext.wtmap.get(windturbineId);
                    if (wt.getWindpowerstationId().contains(WpType.GDC.id)) {
                        continue;
                        // item.SPEED = Double.Truncate(pointsF1[i].X);
                    } else {
                        item.setSpeed(sjglls.get(i).getX());

                    }
                    item.setActualPower(sjglls.get(i).getY());
                    item.setOptimalPower(zyglls.get(i).getY());
                    item.setYear(String.valueOf(year));
                    wtcfls.add(item);
                    // proEconWtCurveFittingYearService.save(item);
                }

            }
        } else {
            logger.warn(String.format("下标不一致的风机编号：{0}，实际功率：{1}，最有功率：{2}", windturbineId, sjglls.size(), zyglls.size()));


            for (int i = 0; i < sjglls.size(); i++) {
                ProEconWtCurveFittingYear item = new ProEconWtCurveFittingYear();
                item.setWindturbineId(windturbineId);
                if (CacheContext.wtmap.containsKey(windturbineId)) {

                    ProBasicEquipment wt = CacheContext.wtmap.get(windturbineId);
                    if (wt.getWindpowerstationId().contains(WpType.GDC.id)) {
                        continue;
                        //item.SPEED = Double.Truncate(pointsF1[i].X);
                    } else {

                        item.setSpeed(sjglls.get(i).getX());
                    }
                    item.setActualPower(sjglls.get(i).getY());

                    int finalI = i;
                    OptionalDouble op = zyglls.stream().filter(x -> Objects.equals(x.getX(), sjglls.get(finalI).getX())).mapToDouble(PointVo::getY).findFirst();

                    if (op.isPresent()) {
                        item.setOptimalPower(op.getAsDouble());
                    } else {
                        item.setOptimalPower(0.0);
                    }

                    item.setYear(String.valueOf(year));
                    wtcfls.add(item);
                    //proEconWtCurveFittingYearService.save(item);
                }

            }
        }
        //*********************************************当年曲线偏差记录**********************************************************/

        List<ProEconWtCurveFittingYear> templs = new ArrayList<>();
        for (ProEconWtCurveFittingYear vo : wtcfls) {
            templs.add(vo);
            if (templs.size() == 1000) {
                proEconWtCurveFittingYearService.saveOrUpdateBatch(templs);
                templs = new ArrayList<>();
            }
        }

        if (!templs.isEmpty()) {
            proEconWtCurveFittingYearService.saveOrUpdateBatch(templs);
        }
        //        proEconWtCurveFittingYearService.saveBatch(wtcfls);
        String s = JSONObject.toJSONString(wtcfls);
        redisService.set(CurveType.yearCurve.id + "_" + windturbineId, s);
    }

    private void insertPoints2(List<PointVo> monthSjglls, List<PointVo> monthZyglls, String windturbineId) {


        //        List<Integer> wtpcfidls = proEconWtPowerCurveFittingService.list()
        //                .stream().filter(i -> i.getWindturbineId().equals(windturbineId))
        //                .map(ProEconWtPowerCurveFitting::getId).collect(Collectors.toList());
        //
        //
        //        for (int i = 0; i < wtpcfidls.size(); i++) {
        //            proEconWtPowerCurveFittingService.removeByIds(wtpcfidls);
        //        }

        proEconWtPowerCurveFittingService.deleteProEconWtPowerCurveFitting();

        List<ProEconWtPowerCurveFitting> wtcfls = new ArrayList<>();
        if (monthSjglls.size() == monthZyglls.size()) {
            for (int i = 0; i < monthSjglls.size(); i++) {
                ProEconWtPowerCurveFitting item = new ProEconWtPowerCurveFitting();

                item.setWindturbineId(windturbineId);

                if (CacheContext.wtmap.containsKey(windturbineId)) {

                    ProBasicEquipment wt = CacheContext.wtmap.get(windturbineId);
                    if (wt.getWindpowerstationId().contains(WpType.GDC.id)) {
                        continue;
                        // item.SPEED = Double.Truncate(pointsF1[i].X);
                    } else {
                        boolean l = String.valueOf(monthSjglls.get(i).getX()).contains(".");
                        if (l) {
                            continue;
                        }
                        item.setSpeed(monthSjglls.get(i).getX());
                    }


                    item.setActualPower(monthSjglls.get(i).getY());
                    item.setOptimalPower(monthZyglls.get(i).getY());

                    wtcfls.add(item);
                    //proEconWtPowerCurveFittingService.save(item);
                }

            }
        } else {

            logger.warn(String.format("下标不一致的风机编号：{0}，实际功率：{1}，最有功率：{2}", windturbineId, monthSjglls.size(), monthZyglls.size()));

            for (int i = 0; i < monthSjglls.size(); i++) {
                ProEconWtPowerCurveFitting item = new ProEconWtPowerCurveFitting();

                item.setWindturbineId(windturbineId);

                if (CacheContext.wtmap.containsKey(windturbineId)) {

                    ProBasicEquipment wt = CacheContext.wtmap.get(windturbineId);
                    if (wt.getWindpowerstationId().contains(WpType.GDC.id)) {
                        continue;
                        //item.SPEED = Double.Truncate(pointsF1[i].X);
                    } else {
                        boolean l = String.valueOf(monthSjglls.get(i).getX()).contains(".");
                        if (l) {
                            continue;
                        }
                        item.setSpeed(monthSjglls.get(i).getX());
                    }


                    item.setActualPower(monthSjglls.get(i).getY());
                    int finalI = i;
                    OptionalDouble op = monthZyglls.stream().filter(x -> Objects.equals(x.getX(), monthSjglls.get(finalI).getX())).mapToDouble(PointVo::getY).findFirst();

                    if (op.isPresent()) {
                        item.setOptimalPower(op.getAsDouble());
                    } else {
                        item.setOptimalPower(0.0);
                    }

                    wtcfls.add(item);
                    //proEconWtPowerCurveFittingService.save(item);
                }

            }
        }

        List<ProEconWtPowerCurveFitting> templs = new ArrayList<>();
        for (ProEconWtPowerCurveFitting vo : wtcfls) {
            templs.add(vo);
            if (templs.size() == 1000) {
                proEconWtPowerCurveFittingService.saveOrUpdateBatch(templs);
                templs = new ArrayList<>();
            }
        }

        if (!templs.isEmpty()) {
            proEconWtPowerCurveFittingService.saveOrUpdateBatch(templs);
        }
        //        proEconWtPowerCurveFittingService.saveBatch(wtcfls);
    }

    private void yearBuildPoints(List<ProEconWtCurveFittingYear> data, List<PointVo> points) {
        if (data != null) {
            for (ProEconWtCurveFittingYear datum : data) {
                PointVo point = new PointVo();
                point.setX(datum.getSpeed());
                point.setY(datum.getActualPower());
                points.add(point);
            }
        }
    }

    private void monthBuildPoints(List<ProEconWtCurveFittingMonth> data, List<PointVo> points) {
        if (data != null) {
            for (ProEconWtCurveFittingMonth datum : data) {
                PointVo point = new PointVo();
                point.setX(datum.getSpeed());
                point.setY(datum.getActualPower());
                points.add(point);
            }
        }
    }

    private void dayBuildPoints(List<ProEconWtCurveFitting> data, List<PointVo> points) {
        if (data != null) {
            for (ProEconWtCurveFitting datum : data) {
                PointVo point = new PointVo();
                point.setX(datum.getSpeed());
                point.setY(datum.getActualPower());
                points.add(point);
            }
        }
    }

    //曲线偏差率
    private double pcl(List<PointVo> points1, List<PointVo> points2, Double modelpower) {
        double result = -0;
        double pc = 0;
        if (points1 != null && points1.size() != 0 && points2 != null && points2.size() != 0) {
            double count = 0;
            double sum = 0;
            double max = modelpower;
            for (PointVo point : points1) {
                List<PointVo> item = points2.stream().filter(it -> Objects.equals(it.getX(), point.getX())).collect(Collectors.toList());
                if (item.size() > 0) {
                    sum += Math.pow((point.getY() - item.get(0).getY()), 2);
                    count++;
                    pc += point.getY() - item.get(0).getY();
                }
            }
            sum = Math.sqrt(sum);
            count = Math.sqrt(count);
            max = max * count;
            if (max != 0) {
                result = sum / max * 100;
            }

            if (pc < 0) {
                result = 0 - result;
            }
        }
        return result;
    }

    //曲线偏差率2
    private double pcl2(List<PointVo> points1, List<PointVo> points2, Double modelpower, double speed) {
        double minSpeed = speed;
        double maxSpeed = minSpeed + 1;
        double result = -0;
        double pc = 0;
        if (points1 != null && points1.size() != 0 && points2 != null && points2.size() != 0) {
            double count = 0;
            double sum = 0;
            double max = modelpower;
            for (PointVo point : points1) {
                List<PointVo> item = points2.stream().filter(it -> Objects.equals(it.getX(), point.getX())).collect(Collectors.toList());
                if (item.size() > 0 && item.get(0).getX() >= minSpeed && item.get(0).getX() < maxSpeed) {
                    sum += Math.pow((point.getY() - item.get(0).getY()), 2);
                    count++;
                    pc += point.getY() - item.get(0).getY();
                }
            }
            sum = Math.sqrt(sum);
            count = Math.sqrt(count);
            max = max * count;
            if (max != 0) {
                result = sum / max * 100;
            }

            if (pc < 0) {
                result = 0 - result;
            }
        }
        return result;
    }

    //todo-sl 添加数据筛选
    private boolean filterData(PointData gl, PointData fs, List<PointData> ztls, List<PointData> qfztls, int i, double maxPower, double maxSpeed, String windturbineId) throws Exception {
        if (StringUtils.notEmp(gl)) {
            //判定功率是否超过最大值
            if (gl.getPointValueInDouble() > maxPower || gl.getPointValueInDouble() < 0) {
                return false;
            }
        }

        if (StringUtils.notEmp(fs)) {
            //判定功率是否超过最大值
            if (fs.getPointValueInDouble() > maxSpeed || fs.getPointValueInDouble() < 0) {
                return false;
            }
        }

        //判定状态不为运行的进行过滤
        if (ztls.get(i).getPointValueInDouble() != 2) {
            return false;
        }


        if (i < 10) {
            return false;
        } else {

            for (int j = i - 10; j < i; j++) {
                //设置时间为10分钟前，10钟前有停机事件数据进行过滤
                if (ztls.get(j).getPointValueInDouble() == 4) {

                    return false;
                }
                //设置时间为10分钟后，运行后10分钟数据进行过滤
                if (ztls.get(j).getPointValueInDouble() != 2) {

                    return false;
                }
            }
        }


        //        List<PointVo> bzPointls=new ArrayList<>();
        //        List<PointVo> sjPointls=new ArrayList<>();
        //
        //        double modelpower=0.0;
        //        if (CacheContext.wtmap.containsKey(windturbineId)) {
        //            String modelid = CacheContext.wtmap.get(windturbineId).getModelId();
        //            if (StringUtils.notEmp(modelid)) {
        //                //获取保证功率曲线中的风速和功率
        //                if (CacheContext.theoreticalPowerMap.containsKey(modelid)) {
        //                    Map<Double,ProBasicModelPowerRd> theoreticalMap= CacheContext.theoreticalPowerMap.get(modelid);
        //
        //                    PointVo point = new PointVo();
        //                    double speed=StringUtils.round(fs.getPointValueInDouble(),2);
        //                    point.setX(speed);
        //                    point.setY(theoreticalMap.get(speed).getEnsurePower());
        //
        //                    modelpower=point.getY();
        //                    bzPointls.add(point);
        //                }
        //            }
        //        }
        //
        //        PointVo point = new PointVo();
        //        double speed=StringUtils.round(fs.getPointValueInDouble(),2);
        //        double power=StringUtils.round(gl.getPointValueInDouble(),2);
        //        point.setX(speed);
        //        point.setY(power);
        //        sjPointls.add(point);

        //与保证功率进行对比，偏差大于1000%的进行过滤
        //        double value= pcl2( sjPointls, bzPointls, modelpower, speed);
        //
        //        if (0.1000 > Math.abs(value)) {
        //            return false;
        //        }

        double modelpower = 0.0;
        if (CacheContext.wtmap.containsKey(windturbineId)) {
            String modelid = CacheContext.wtmap.get(windturbineId).getModelId();
            if (StringUtils.notEmp(modelid)) {
                //获取保证功率曲线中的风速和功率
                if (CacheContext.theoreticalPowerMap.containsKey(modelid)) {
                    Map<Double, ProBasicModelPowerRd> theoreticalMap = CacheContext.theoreticalPowerMap.get(modelid);


                    double speed = StringUtils.round(fs.getPointValueInDouble(), 2);

                    if (theoreticalMap.containsKey(speed)) {
                        modelpower = theoreticalMap.get(speed).getEnsurePower();
                    } else {
                        modelpower = 0;
                    }


                }
            }
        }
        if (gl.getPointValueInDouble() > (modelpower * 1.1000) || gl.getPointValueInDouble() < (modelpower * 0.75)) {
            return false;
        }

        //        Map<String, Map<String, ProBasicEquipmentPoint>> wtpAimap = CacheContext.wtpAimap;
        //        Map<String, ProBasicEquipmentPoint> wtpointmap = wtpAimap.get(windturbineId);
        //        List<String> pointid = new ArrayList<>();
        //        //欠发状态大于2过滤掉
        //        pointid.add(wtpointmap.get(ContantXk.LSQFZT).getNemCode());
        //        List<PointData> values = edosUtil.getHistMatrix(pointid, gl.getPointTime() / 1000);
        //        if (null != values && values.size() > 0) {
        //            double qfzt = qfztls.get(i).getPointValueInDouble();
        //
        //            return !(qfzt > 2);
        //        }


        //欠发状态大于2过滤掉
        if (qfztls.get(i).getPointValueInDouble() > 2) {

            return false;
        }
        return true;
    }

    //功率曲线拟合
    private void curveFittingBuilder(Date begin, Date end, int dimension, double scale, String pointIdGL, String pointIdFS, String pointIdZT, List<PointVo> sjglPoints, List<PointVo> zyglPoints, String windturbineId) throws Exception {
        double maxPower = windturbineCapacity.get(windturbineId) * 1.3;
        double maxSpeed = 1000;
        List<PointfVo> sjglnhpoints = new ArrayList<>();
        Map<Double, PointfVo> zyglnhpoints = new HashMap<>();

        Map<String, Map<String, ProBasicEquipmentPoint>> wtpAimap = CacheContext.wtpAimap;
        Map<String, ProBasicEquipmentPoint> wtpointmap = wtpAimap.get(windturbineId);
        String qfzt = wtpointmap.get(ContantXk.LSQFZT).getNemCode();

        if (end.after(begin)) {
            if (StringUtils.notEmp(pointIdGL) && StringUtils.notEmp(pointIdFS)) {
                List<PointData> glpointstemp = edosUtil.getHistoryDatasSnap(pointIdGL, begin.getTime() / 1000, end.getTime() / 1000);
                List<PointData> fspointstemp = edosUtil.getHistoryDatasSnap(pointIdFS, begin.getTime() / 1000, end.getTime() / 1000);
                List<PointData> ztpointstemp = edosUtil.getHistoryDatasSnap(pointIdZT, begin.getTime() / 1000, end.getTime() / 1000);
                List<PointData> qfzttemp = edosUtil.getHistoryDatasSnap(qfzt, begin.getTime() / 1000, end.getTime() / 1000);


                List<PointData> glpoints = new ArrayList<>();
                List<PointData> fspoints = new ArrayList<>();
                List<PointData> ztpoints = new ArrayList<>();
                if (!glpointstemp.isEmpty() && !fspointstemp.isEmpty() && !ztpointstemp.isEmpty() && glpointstemp.size() == fspointstemp.size() && fspointstemp.size() == ztpointstemp.size()) {
                    for (int i = 0; i < glpointstemp.size(); i++) {
                        if (filterData(glpointstemp.get(i), fspointstemp.get(i), ztpointstemp, qfzttemp, i, maxPower, maxSpeed, windturbineId)) {
                            glpoints.add(glpointstemp.get(i));
                            fspoints.add(fspointstemp.get(i));
                            ztpoints.add(ztpointstemp.get(i));
                        }
                    }
                }


                if (glpoints.size() != fspoints.size() || glpoints.size() != ztpoints.size()) {
                    for (int i = 0; i < fspoints.size(); i++) {
                        double x = fspoints.get(i).getPointValueInDouble();
                        double y = -1;
                        double z = -1;

                        int finalI1 = i;
                        List<PointData> yArray = glpoints.stream().filter(it -> it.getPointTime().compareTo(fspoints.get(finalI1).getPointTime()) == 0).collect(Collectors.toList());
                        if (yArray.size() > 0) {

                            y = yArray.get(0).getPointValueInDouble();
                        }

                        int finalI = i;
                        yArray = ztpoints.stream().filter(it -> it.getPointTime().compareTo(fspoints.get(finalI).getPointTime()) == 0).collect(Collectors.toList());
                        if (yArray.size() > 0) {

                            z = yArray.get(0).getPointValueInDouble();
                        }


                        Double x1 = StringUtils.round(x, 2);
                        Double y1 = y;


                        boolean b = true;

                        if (CacheContext.wtmap.containsKey(windturbineId)) {

                            ProBasicEquipment wt = CacheContext.wtmap.get(windturbineId);
                            if (wt.getWindpowerstationId().contains(WpType.GDC.id)) {
                                b = (x >= 0 && y > 0);
                            } else {
                                if (z == 2) {

                                    b = (x >= 0 && x <= 30 && y >= 0 && y <= maxPower);

                                    if (b) {
                                        if (x > 3 && y <= 0) {
                                            b = false;
                                        }
                                        if (x <= 3 && y > 0) {
                                            b = false;
                                        }
                                    }

                                } else {
                                    b = false;
                                }
                            }

                        }

                        if (b) {
                            sjglnhpoints.add(new PointfVo(x1, y1));

                            if (zyglnhpoints.containsKey(x1)) {
                                if (zyglnhpoints.get(x1).getY() < y1) {
                                    zyglnhpoints.put(x1, new PointfVo(x1, y1));

                                }
                            } else {
                                zyglnhpoints.put(x1, new PointfVo(x1, y1));
                            }


                        }


                    }
                } else {

                    for (int i = 0; i < fspoints.size(); i++) {
                        double x = fspoints.get(i).getPointValueInDouble();
                        double y = glpoints.get(i).getPointValueInDouble();
                        double z = ztpoints.get(i).getPointValueInDouble();


                        Double x1 = StringUtils.round(x, 2);
                        Double y1 = y;


                        boolean b = true;
                        if (CacheContext.wtmap.containsKey(windturbineId)) {

                            ProBasicEquipment wt = CacheContext.wtmap.get(windturbineId);
                            if (wt.getWindpowerstationId().contains(WpType.GDC.id)) {
                                b = (x >= 0 && y > 0);
                            } else {
                                if (z == 2) {

                                    b = (x >= 0 && x <= 30 && y >= 0 && y <= maxPower);

                                    if (b) {
                                        if (x > 3 && y <= 0) {
                                            b = false;
                                        }
                                        if (x <= 3 && y > 0) {
                                            b = false;
                                        }
                                    }

                                } else {
                                    b = false;
                                }
                            }
                        }

                        if (b) {
                            sjglnhpoints.add(new PointfVo(x1, y1));

                            if (zyglnhpoints.containsKey(x1)) {
                                if (zyglnhpoints.get(x1).getY() < y1) {
                                    zyglnhpoints.put(x1, new PointfVo(x1, y1));

                                }
                            } else {
                                zyglnhpoints.put(x1, new PointfVo(x1, y1));
                            }

                        }
                    }
                }
                sjglnhpoints.add(new PointfVo(0.0, 0.0));

                sjglnhpoints = sjglnhpoints.stream().filter(it -> it.getX() >= 3).sorted(Comparator.comparing(PointfVo::getX)).collect(Collectors.toList());
                //                if (sjglnhpoints.stream().min(Comparator.comparing(PointfVo::getX)).isPresent()) {
                //                    double  Xmax = sjglnhpoints.stream().max(Comparator.comparing(PointfVo::getX)).get().getX();
                //                    double  Ymax = sjglnhpoints.stream().max(Comparator.comparing(PointfVo::getX)).get().getY();
                //                    System.out.println("");
                //                }

                List<PointVo> temp = LineUtil.buildLine(sjglnhpoints.stream().mapToDouble(PointfVo::getX).toArray(), sjglnhpoints.stream().mapToDouble(PointfVo::getY).toArray(), sjglnhpoints.size(), dimension, scale);

                sjglPoints.addAll(temp);
                if (sjglPoints.size() != 0) {
                    buildMyPoints(sjglPoints, scale);
                }


                if (!zyglnhpoints.containsKey(0.0))
                    zyglnhpoints.put(0.0, new PointfVo(0.0, 0.0));

                List<PointfVo> zygltemp = zyglnhpoints.values().stream().filter(it -> it.getX() >= 3).sorted(Comparator.comparing(PointfVo::getX)).collect(Collectors.toList());
                if (zygltemp.size() != 0) {
                    temp = LineUtil.buildLine(zygltemp.stream().mapToDouble(PointfVo::getX).toArray(), zygltemp.stream().mapToDouble(PointfVo::getY).toArray(), zygltemp.size(), dimension, scale);
                }
                zyglPoints.addAll(temp);
                if (zyglPoints.size() != 0) {
                    buildMyPoints(zyglPoints, scale);
                }
            }
        }
    }

    private static void buildMyPoints(List<PointVo> sjglPoints, double scale) {
        int coefficient = 1;
        int dec = 0;
        int smax = 1000;
        if (scale == 0.01) {
            coefficient = 100;
            dec = 2;
        }
        if (scale == 0.1) {
            coefficient = 10;
            dec = 1;
        }

        smax *= coefficient;


        double min = 0.0;
        double max = 0.0;
        double maxval = 0.0;
        if (sjglPoints.stream().min(Comparator.comparing(PointVo::getX)).isPresent()) {
            min = sjglPoints.stream().min(Comparator.comparing(PointVo::getX)).get().getX() * coefficient;

        }
        if (sjglPoints.stream().max(Comparator.comparing(PointVo::getX)).isPresent()) {
            max = sjglPoints.stream().max(Comparator.comparing(PointVo::getX)).get().getX() * coefficient;
        }
        if (sjglPoints.stream().max(Comparator.comparing(PointVo::getY)).isPresent()) {
            maxval = sjglPoints.stream().max(Comparator.comparing(PointVo::getY)).get().getY();
        }


        for (double i = 0; i < min; i += 1) {
            PointVo point = new PointVo();
            point.setX(StringUtils.round(i / coefficient, dec));
            point.setY(0.0);

            sjglPoints.add(point);
        }


        for (double i = smax; i > max; i -= 1) {
            PointVo point = new PointVo();
            point.setX(StringUtils.round(i / coefficient, dec));
            point.setY(maxval);

            sjglPoints.add(point);
        }
    }

}
