package com.ruoyi.predict.api;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.json.JSONObject;
import com.ruoyi.common.utils.DateTimeUtil;
import com.ruoyi.predict.domain.*;
import com.ruoyi.predict.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author hlf
 * @date 2022/9/22 15:20
 * 文件说明：功率管控
 */
@Api(value = "功率管控Controller", tags = {"功率管控操作接口"})
@Controller
@RequestMapping("/predict/api/pmc")
public class PowerManagementController extends BaseController {

    private static DefaultWebSecurityManager manager = new DefaultWebSecurityManager();

    @Autowired
    private IWfFileConfigService wfFileConfigService;

    @Autowired
    private IWindplantprojectService windplantprojectService;

    @Autowired
    private ICollectorwireprojectService collectorwireprojectService;

    @Autowired
    private INoscalePrDaPfPeriodDataService noscalePrDaPfPeriodDataService;

    @Autowired
    private IProjectUspTsPeriodDataService projectUspTsPeriodDataService;

    @Autowired
    private IWfYcHistoryData1Service wfYcHistoryData1Service;

    @Autowired
    private INoscaleCwDaPfPeriodDataService noscaleCwDaPfPeriodDataService;

    @Autowired
    private ICwUspTsPeriodDataService cwUspTsPeriodDataService;

    @Autowired
    private INoscaleWtgDaPfPeriodDataService noscaleWtgDaPfPeriodDataService;

    @Autowired
    private IMvService mvService;

    @Autowired
    private IWtgTheorypowerDataService wtgTheorypowerDataService;

    @Autowired
    private IWfYcHistoryData2Service wfYcHistoryData2Service;

    @Autowired
    private IProjectEuspTsPeriodDataService projectEuspTsPeriodDataService;

    @Autowired
    private INoscalePrDaEfPeriodDataService noscalePrDaEfPeriodDataService;

    @Autowired
    private IPlanpowerDistributionService planpowerDistributionService;

    @Autowired
    private IProjectplanService projectplanService;

    @Autowired
    private INoscaleCwDaEfPeriodDataService noscaleCwDaEfPeriodDataService;

    @Autowired
    private IBcrService bcrService;

    @Autowired
    private INoscaleWtgDaEfPeriodDataService noscaleWtgDaEfPeriodDataService;

    @Autowired
    private IWturService wturService;

    @Autowired
    private IWtgStopPlantService wtgStopPlantService;

    @Autowired
    private IWfProjectCwWtgService wfProjectCwWtgService;

    @Autowired
    private IWfStatPeriodDataService wfStatPeriodDataService;

    @ApiOperation("场站概览")
    @GetMapping("/terminalOverview")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(name = "stationNumber", value = "场站编号", required = true),
            @ApiImplicitParam(name = "windplantprojectCount", value = "总期次数"),
            @ApiImplicitParam(name = "collectorwireprojectCount", value = "总集电线数"),
            @ApiImplicitParam(name = "wturCount", value = "总风机数"),
            @ApiImplicitParam(name = "avgWindSpeed", value = "平均风速"),
            @ApiImplicitParam(name = "p0", value = "实际功率"),
    })
    public AjaxResult terminalOverview(@RequestParam(value = "stationNumber") String stationNumber) {
        JSONObject json = new JSONObject();
        //总期次数
        List<Windplantproject> windplantprojectList = windplantprojectService.selectWindplantprojectByWindplantNo(Convert.toLong(stationNumber));
        int windplantprojectCount = windplantprojectList.size();
        //总集电线数
        List<Collectorwireproject> collectorwireprojectList = collectorwireprojectService.selectCollectorwireprojectByWindplantNo(Convert.toLong(stationNumber));
        int collectorwireprojectCount = collectorwireprojectList.size();
        //总风机数
        List<WfProjectCwWtg> wfProjectCwWtgList = wfProjectCwWtgService.selectWfProjectCwWtgByWindplantNo(Convert.toLong(stationNumber));
        int wturCount = wfProjectCwWtgList.size();
        Map<String, Object> params = new HashMap<>();
        params.put("beginDataTime", DateUtil.formatDateTime(DateUtil.beginOfDay(DateUtil.date())));
        params.put("endDataTime", DateUtil.formatDateTime(DateUtil.date(DateUtil.endOfDay(DateUtil.date()).getTime() + 1000)));
        WfStatPeriodData wfStatPeriodData = new WfStatPeriodData();
        wfStatPeriodData.setWindplantNo(Convert.toLong(stationNumber));
        wfStatPeriodData.setParams(params);
        List<WfStatPeriodData> wfStatPeriodDataList = wfStatPeriodDataService.selectWfStatPeriodDataList(wfStatPeriodData);
        //平均风速
        double avgWindSpeed = 0;
        //实际功率
        double p0 = 0;
        if (wfStatPeriodDataList.size() > 0) {
            avgWindSpeed = wfStatPeriodDataList.get(wfStatPeriodDataList.size() - 1).getAvgWindSpeed();
            p0 = wfStatPeriodDataList.get(wfStatPeriodDataList.size() - 1).getP0();
        }
        json.put("windplantprojectCount", windplantprojectCount);
        json.put("collectorwireprojectCount", collectorwireprojectCount);
        json.put("wturCount", wturCount);
        json.put("avgWindSpeed", avgWindSpeed);
        json.put("p0", p0);
        return AjaxResult.success(json);
    }

    @ApiOperation("功率预测-期次")
    @GetMapping("/powerPredictionQc")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "唯一主键", required = true),
    })
    public AjaxResult powerPredictionQc(@RequestParam(value = "id") String id) {
        JSONObject json = new JSONObject();
        //当日的开始时间
        Date beginOfDay = DateUtil.date(DateUtil.beginOfDay(DateUtil.date()).getTime() + 900000);
        //当日的结束时间
        Date endOfDay = DateUtil.date(DateUtil.endOfDay(DateUtil.date()).getTime() + 1000);
        //获取所有时间
        List<Date> dateList = DateTimeUtil.getDateList15(DateUtil.parse(DateUtil.formatDateTime(beginOfDay)), DateUtil.parse(DateUtil.formatDateTime(endOfDay)));
        LinkedMultiValueMap<String, Double> map = new LinkedMultiValueMap<String, Double>();
        Map<String, Object> params = new HashMap<>();
        params.put("beginDataTime", DateUtil.formatDateTime(beginOfDay));
        params.put("endDataTime", DateUtil.formatDateTime(endOfDay));
        String[] ids = id.split("/");
        if (ids.length == 2) {
            Long windplantNo = Convert.toLong(ids[0]);
            Long projectNo = Convert.toLong(ids[1]);
            WfFileConfig wfFileConfig = wfFileConfigService.selectWfFileConfigById(windplantNo);
            if (ObjectUtil.isNotNull(wfFileConfig)) {
                /*短期预测开始*/
                NoscalePrDaPfPeriodData noscalePrDaPfPeriodData = new NoscalePrDaPfPeriodData();
                noscalePrDaPfPeriodData.setWfPrNo(projectNo);
                noscalePrDaPfPeriodData.setModelNo(wfFileConfig.getWpfmodelNo());
                noscalePrDaPfPeriodData.setParams(params);
                List<NoscalePrDaPfPeriodData> noscalePrDaPfPeriodDataList = noscalePrDaPfPeriodDataService.selectNoscalePrDaPfPeriodDataList(noscalePrDaPfPeriodData);
                for (NoscalePrDaPfPeriodData n : noscalePrDaPfPeriodDataList) {
                    String dataTime = DateUtil.format(n.getDataTime(), "yyyy-MM-dd HH:mm");
                    ShareController.addMapValue(map, n.getValue(), dataTime, 0, 1);
                }
                /*短期预测结束*/
                /*超短期预测开始*/
                ProjectUspTsPeriodData projectUspTsPeriodData = new ProjectUspTsPeriodData();
                projectUspTsPeriodData.setProjectNo(projectNo);
                projectUspTsPeriodData.setModelNo(wfFileConfig.getUwpfmodelNo());
                projectUspTsPeriodData.setTimeScale((long) 0);
                projectUspTsPeriodData.setParams(params);
                List<ProjectUspTsPeriodData> projectUspTsPeriodDataList = projectUspTsPeriodDataService.selectProjectUspTsPeriodDataList(projectUspTsPeriodData);
                for (ProjectUspTsPeriodData p : projectUspTsPeriodDataList) {
                    String dataTime = DateUtil.format(p.getDataTime(), "yyyy-MM-dd HH:mm");
                    ShareController.addMapValue(map, p.getModPower(), dataTime, 1, 2);
                }
                /*超短期预测结束*/
                /*实际开始*/
                Windplantproject windplantproject = windplantprojectService.selectWindplantprojectByWpNoProjectNo(windplantNo, projectNo);
                if (ObjectUtil.isNotNull(windplantproject)) {
                    WfYcHistoryData1 wfYcHistoryData1 = new WfYcHistoryData1();
                    wfYcHistoryData1.setAnalogNo(windplantproject.getAnalogNo());
                    wfYcHistoryData1.setParams(params);
                    List<WfYcHistoryData1> wfYcHistoryData1List = wfYcHistoryData1Service.selectWfYcHistoryData1List(wfYcHistoryData1);
                    for (WfYcHistoryData1 w : wfYcHistoryData1List) {
                        String dataTime = DateUtil.format(w.getDataTime(), "yyyy-MM-dd HH:mm");
                        ShareController.addMapValue(map, w.getYcVal(), dataTime, 2, 3);
                    }
                }
                /*实际结束*/
            }
        }
        List<DataFormat> dataFormatList = new ArrayList<>();
        String[] nameStr = {"短期", "超短期", "实际"};
        int count1 = dateList.size();
        int v = 1;
        for (int i = 0; i < 3; i++) {
            Double[] data = new Double[count1];
            for (int k = 0; k < count1; k++) {
                List<Double> entry = map.get(DateUtil.format(dateList.get(k), "yyyy-MM-dd HH:mm"));
                if (entry != null) {
                    if (entry.size() >= v) {
                        data[k] = entry.get(i);
                    }
                }
            }
            DataFormat dataFormat = new DataFormat();
            dataFormat.setName(nameStr[i]);
            dataFormat.setData(data);
            dataFormatList.add(dataFormat);
            v++;
        }
        json.put("dataFormatList", dataFormatList);
        json.put("dateList", dateList);
        return AjaxResult.success(json);
    }

    @ApiOperation("功率预测-集电线")
    @GetMapping("/powerPredictionJdx")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "唯一主键", required = true),
    })
    public AjaxResult powerPredictionJdx(@RequestParam(value = "id") String id) {
        JSONObject json = new JSONObject();
        //当日的开始时间
        Date beginOfDay = DateUtil.date(DateUtil.beginOfDay(DateUtil.date()).getTime() + 900000);
        //当日的结束时间
        Date endOfDay = DateUtil.date(DateUtil.endOfDay(DateUtil.date()).getTime() + 1000);
        //获取所有时间
        List<Date> dateList = DateTimeUtil.getDateList15(DateUtil.parse(DateUtil.formatDateTime(beginOfDay)), DateUtil.parse(DateUtil.formatDateTime(endOfDay)));
        LinkedMultiValueMap<String, Double> map = new LinkedMultiValueMap<String, Double>();
        Map<String, Object> params = new HashMap<>();
        params.put("beginDataTime", DateUtil.formatDateTime(beginOfDay));
        params.put("endDataTime", DateUtil.formatDateTime(endOfDay));
        String[] ids = id.split("/");
        if (ids.length == 3) {
            Long windplantNo = Convert.toLong(ids[0]);
            Long projectNo = Convert.toLong(ids[1]);
            Long collectorwireNo = Convert.toLong(ids[2]);
            WfFileConfig wfFileConfig = wfFileConfigService.selectWfFileConfigById(windplantNo);
            if (ObjectUtil.isNotNull(wfFileConfig)) {
                /*短期预测开始*/
                NoscaleCwDaPfPeriodData noscaleCwDaPfPeriodData = new NoscaleCwDaPfPeriodData();
                noscaleCwDaPfPeriodData.setWfPrCwireNo(collectorwireNo);
                noscaleCwDaPfPeriodData.setModelNo(wfFileConfig.getWpfmodelNo());
                noscaleCwDaPfPeriodData.setParams(params);
                List<NoscaleCwDaPfPeriodData> noscaleCwDaPfPeriodDataList = noscaleCwDaPfPeriodDataService.selectNoscaleCwDaPfPeriodDataList(noscaleCwDaPfPeriodData);
                for (NoscaleCwDaPfPeriodData n : noscaleCwDaPfPeriodDataList) {
                    String dataTime = DateUtil.format(n.getDataTime(), "yyyy-MM-dd HH:mm");
                    ShareController.addMapValue(map, n.getValue(), dataTime, 0, 1);
                }
                /*短期预测结束*/
                /*超短期预测开始*/
                CwUspTsPeriodData cwUspTsPeriodData = new CwUspTsPeriodData();
                cwUspTsPeriodData.setWfPrCwireNo(collectorwireNo);
                cwUspTsPeriodData.setModelNo(wfFileConfig.getUwpfmodelNo());
                cwUspTsPeriodData.setTimeScale((long) 0);
                cwUspTsPeriodData.setParams(params);
                List<CwUspTsPeriodData> cwUspTsPeriodDataList = cwUspTsPeriodDataService.selectCwUspTsPeriodDataList(cwUspTsPeriodData);
                for (CwUspTsPeriodData c : cwUspTsPeriodDataList) {
                    String dataTime = DateUtil.format(c.getDataTime(), "yyyy-MM-dd HH:mm");
                    ShareController.addMapValue(map, c.getModPower(), dataTime, 1, 2);
                }
                /*超短期预测结束*/
                /*实际开始*/
                Collectorwireproject collectorwireproject = collectorwireprojectService.selectCollectorwireproject(windplantNo, projectNo, collectorwireNo);
                if (ObjectUtil.isNotNull(collectorwireproject)) {
                    WfYcHistoryData1 wfYcHistoryData1 = new WfYcHistoryData1();
                    wfYcHistoryData1.setAnalogNo(collectorwireproject.getAnalogNo());
                    wfYcHistoryData1.setParams(params);
                    List<WfYcHistoryData1> wfYcHistoryData1List = wfYcHistoryData1Service.selectWfYcHistoryData1List(wfYcHistoryData1);
                    for (WfYcHistoryData1 w : wfYcHistoryData1List) {
                        String dataTime = DateUtil.format(w.getDataTime(), "yyyy-MM-dd HH:mm");
                        ShareController.addMapValue(map, w.getYcVal(), dataTime, 2, 3);
                    }
                }
                /*实际结束*/
            }
        }
        List<DataFormat> dataFormatList = new ArrayList<>();
        String[] nameStr = {"短期", "超短期", "实际"};
        int count1 = dateList.size();
        int v = 1;
        for (int i = 0; i < 3; i++) {
            Double[] data = new Double[count1];
            for (int k = 0; k < count1; k++) {
                List<Double> entry = map.get(DateUtil.format(dateList.get(k), "yyyy-MM-dd HH:mm"));
                if (entry != null) {
                    if (entry.size() >= v) {
                        data[k] = entry.get(i);
                    }
                }
            }
            DataFormat dataFormat = new DataFormat();
            dataFormat.setName(nameStr[i]);
            dataFormat.setData(data);
            dataFormatList.add(dataFormat);
            v++;
        }
        json.put("dataFormatList", dataFormatList);
        json.put("dateList", dateList);
        return AjaxResult.success(json);
    }

    @ApiOperation("功率预测-风机")
    @GetMapping("/powerPredictionFj")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "唯一主键", required = true),
    })
    public AjaxResult powerPredictionFj(@RequestParam(value = "id") String id) {
        JSONObject json = new JSONObject();
        //当日的开始时间
        Date beginOfDay = DateUtil.date(DateUtil.beginOfDay(DateUtil.date()).getTime() + 900000);
        //当日的结束时间
        Date endOfDay = DateUtil.date(DateUtil.endOfDay(DateUtil.date()).getTime() + 1000);
        //获取所有时间
        List<Date> dateList = DateTimeUtil.getDateList15(DateUtil.parse(DateUtil.formatDateTime(beginOfDay)), DateUtil.parse(DateUtil.formatDateTime(endOfDay)));
        LinkedMultiValueMap<String, Double> map = new LinkedMultiValueMap<String, Double>();
        Map<String, Object> params = new HashMap<>();
        params.put("beginDataTime", DateUtil.formatDateTime(beginOfDay));
        params.put("endDataTime", DateUtil.formatDateTime(endOfDay));
        String[] ids = id.split("/");
        if (ids.length == 4) {
            Long windplantNo = Convert.toLong(ids[0]);
            Long wturNo = Convert.toLong(ids[3]);
            WfFileConfig wfFileConfig = wfFileConfigService.selectWfFileConfigById(windplantNo);
            if (ObjectUtil.isNotNull(wfFileConfig)) {
                /*理论开始*/
                WtgTheorypowerData wtgTheorypowerData = new WtgTheorypowerData();
                wtgTheorypowerData.setWturNo(wturNo);
                wtgTheorypowerData.setParams(params);
                List<WtgTheorypowerData> wtgTheorypowerDataList = wtgTheorypowerDataService.selectWtgTheorypowerDataList(wtgTheorypowerData);
                for (WtgTheorypowerData w : wtgTheorypowerDataList) {
                    String dataTime = DateUtil.format(w.getDataTime(), "yyyy-MM-dd HH:mm");
                    ShareController.addMapValue(map, w.getTheorypower(), dataTime, 0, 1);
                }
                /*理论结束*/
                /*短期预测开始*/
                NoscaleWtgDaPfPeriodData noscaleWtgDaPfPeriodData = new NoscaleWtgDaPfPeriodData();
                noscaleWtgDaPfPeriodData.setWtgNo(wturNo);
                noscaleWtgDaPfPeriodData.setModelNo(wfFileConfig.getWpfmodelNo());
                noscaleWtgDaPfPeriodData.setParams(params);
                List<NoscaleWtgDaPfPeriodData> noscaleWtgDaPfPeriodDataList = noscaleWtgDaPfPeriodDataService.selectNoscaleWtgDaPfPeriodDataList(noscaleWtgDaPfPeriodData);
                for (NoscaleWtgDaPfPeriodData n : noscaleWtgDaPfPeriodDataList) {
                    String dataTime = DateUtil.format(n.getDataTime(), "yyyy-MM-dd HH:mm");
                    ShareController.addMapValue(map, n.getValue(), dataTime, 1, 2);
                }
                /*短期预测结束*/
                /*实际开始*/
                Mv mv = mvService.selectMvByWturNoRef(wturNo, Convert.toLong(1));
                if (ObjectUtil.isNotNull(mv)) {
                    WfYcHistoryData1 wfYcHistoryData1 = new WfYcHistoryData1();
                    wfYcHistoryData1.setAnalogNo(mv.getMvNo());
                    wfYcHistoryData1.setParams(params);
                    List<WfYcHistoryData1> wfYcHistoryData1List = wfYcHistoryData1Service.selectWfYcHistoryData1List(wfYcHistoryData1);
                    for (WfYcHistoryData1 w : wfYcHistoryData1List) {
                        String dataTime = DateUtil.format(w.getDataTime(), "yyyy-MM-dd HH:mm");
                        ShareController.addMapValue(map, w.getYcVal(), dataTime, 2, 3);
                    }
                }
                /*实际结束*/
            }
        }
        List<DataFormat> dataFormatList = new ArrayList<>();
        String[] nameStr = {"理论", "短期", "实际"};
        int count1 = dateList.size();
        int v = 1;
        for (int i = 0; i < 3; i++) {
            Double[] data = new Double[count1];
            for (int k = 0; k < count1; k++) {
                List<Double> entry = map.get(DateUtil.format(dateList.get(k), "yyyy-MM-dd HH:mm"));
                if (entry != null) {
                    if (entry.size() >= v) {
                        data[k] = entry.get(i);
                    }
                }
            }
            DataFormat dataFormat = new DataFormat();
            dataFormat.setName(nameStr[i]);
            dataFormat.setData(data);
            dataFormatList.add(dataFormat);
            v++;
        }
        json.put("dataFormatList", dataFormatList);
        json.put("dateList", dateList);
        return AjaxResult.success(json);
    }

    @ApiOperation("电量预测-期次")
    @GetMapping("/electricityForecastQc")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "唯一主键", required = true),
    })
    public AjaxResult electricityForecastQc(@RequestParam(value = "id") String id) {
        JSONObject json = new JSONObject();
        //当日的开始时间
        Date beginOfDay = DateUtil.date(DateUtil.beginOfDay(DateUtil.date()).getTime() + 600000);
        //当日的结束时间
        Date endOfDay = DateUtil.date(DateUtil.endOfDay(DateUtil.date()).getTime() + 1000);
        //获取所有时间
        List<Date> dateList = DateTimeUtil.getDateList10(DateUtil.parse(DateUtil.formatDateTime(beginOfDay)), DateUtil.parse(DateUtil.formatDateTime(endOfDay)));
        LinkedMultiValueMap<String, Double> map = new LinkedMultiValueMap<String, Double>();
        Map<String, Object> params = new HashMap<>();
        params.put("beginDataTime", DateUtil.formatDateTime(beginOfDay));
        params.put("endDataTime", DateUtil.formatDateTime(endOfDay));
        String[] ids = id.split("/");
        if (ids.length == 2) {
            Long windplantNo = Convert.toLong(ids[0]);
            Long projectNo = Convert.toLong(ids[1]);
            WfFileConfig wfFileConfig = wfFileConfigService.selectWfFileConfigById(windplantNo);
            if (ObjectUtil.isNotNull(wfFileConfig)) {
                /*实际发电量开始*/
                Windplantproject windplantproject = windplantprojectService.selectWindplantprojectByWpNoProjectNo(windplantNo, projectNo);
                if (ObjectUtil.isNotNull(windplantproject)) {
                    WfYcHistoryData2 wfYcHistoryData2 = new WfYcHistoryData2();
                    wfYcHistoryData2.setAnalogNo(windplantproject.getBcrNo());
                    wfYcHistoryData2.setParams(params);
                    List<WfYcHistoryData2> wfYcHistoryData2List = wfYcHistoryData2Service.selectWfYcHistoryData2List(wfYcHistoryData2);
                    for (WfYcHistoryData2 w : wfYcHistoryData2List) {
                        String dataTime = DateUtil.format(w.getDataTime(), "yyyy-MM-dd HH:mm");
                        ShareController.addMapValue(map, w.getYcRawVal(), dataTime, 0, 1);
                    }
                }
                /*实际发电量结束*/
                /*超短期预测开始*/
                ProjectEuspTsPeriodData projectEuspTsPeriodData = new ProjectEuspTsPeriodData();
                projectEuspTsPeriodData.setProjectNo(projectNo);
                projectEuspTsPeriodData.setModelNo(wfFileConfig.getUwpfemodelNo());
                projectEuspTsPeriodData.setTimeScale((long) 0);
                projectEuspTsPeriodData.setParams(params);
                List<ProjectEuspTsPeriodData> projectEuspTsPeriodDataList = projectEuspTsPeriodDataService.selectProjectEuspTsPeriodDataList(projectEuspTsPeriodData);
                double countModEnergy = 0;
                for (ProjectEuspTsPeriodData p : projectEuspTsPeriodDataList) {
                    String dataTime = DateUtil.format(p.getDataTime(), "yyyy-MM-dd HH:mm");
                    countModEnergy += p.getModEnergy();
                    ShareController.addMapValue(map, countModEnergy, dataTime, 1, 2);
                }
                /*超短期预测结束*/
                /*短期预测开始*/
                NoscalePrDaEfPeriodData noscalePrDaEfPeriodData = new NoscalePrDaEfPeriodData();
                noscalePrDaEfPeriodData.setWfPrNo(projectNo);
                noscalePrDaEfPeriodData.setModelNo(wfFileConfig.getWpfemodelNo());
                noscalePrDaEfPeriodData.setParams(params);
                List<NoscalePrDaEfPeriodData> noscalePrDaEfPeriodDataList = noscalePrDaEfPeriodDataService.selectNoscalePrDaEfPeriodDataList(noscalePrDaEfPeriodData);
                double countValue = 0;
                for (NoscalePrDaEfPeriodData n : noscalePrDaEfPeriodDataList) {
                    String dataTime = DateUtil.format(n.getDataTime(), "yyyy-MM-dd HH:mm");
                    countValue += n.getValue();
                    ShareController.addMapValue(map, countValue, dataTime, 2, 3);
                }
                /*短期预测结束*/
                /*计划发电量开始*/
                PlanpowerDistribution planpowerDistribution = planpowerDistributionService.selectPlanpowerDistributionById(windplantNo);
                if (ObjectUtil.isNotNull(planpowerDistribution)) {
                    List<Projectplan> projectplanList = projectplanService.selectProjectplanByProjectNo(windplantNo, Convert.toStr(projectNo), (long) DateUtil.year(beginOfDay), (long) DateUtil.month(endOfDay) + 1);
                    if (projectplanList.size() > 0){
                        double generatingcapacityCount = projectplanList.stream().mapToDouble(Projectplan::getGeneratingcapacity).sum();
                        double generatingcapacity = 0;
                        if (planpowerDistribution.getType() == 1) {//1为按照去年同期实际发电量分配
                            Map<String, Object> params1 = new HashMap<>();
                            params1.put("beginDataTime", DateUtil.formatDateTime(DateUtil.offsetDay(DateUtil.beginOfDay(DateUtil.date()), 1)));
                            params1.put("endDataTime", DateUtil.formatDateTime(DateUtil.offsetDay(DateUtil.beginOfDay(DateUtil.date()), 14)));
                            NoscalePrDaEfPeriodData obj = new NoscalePrDaEfPeriodData();
                            obj.setWfPrNo(projectNo);
                            obj.setModelNo(wfFileConfig.getWpfemodelNo());
                            obj.setParams(params1);
                            List<NoscalePrDaEfPeriodData> noscalePrDaEfPeriodDataList1 = noscalePrDaEfPeriodDataService.selectNoscalePrDaEfPeriodDataList(obj);
                            long betweenDay = DateUtil.between(DateUtil.beginOfMonth(DateUtil.date()), DateUtil.endOfMonth(DateUtil.date()), DateUnit.DAY) + 1;
                            double a = (double) 13 / (double) betweenDay * generatingcapacityCount;
                            NoscalePrDaEfPeriodData noscalePrDaEfPeriodData1 = noscalePrDaEfPeriodDataService.selectNoscalePrDaEfPeriodDataByJh(projectNo, wfFileConfig.getWpfemodelNo(), DateUtil.offsetDay(DateUtil.beginOfDay(DateUtil.date()), 1));
                            double value = 0;
                            if (ObjectUtil.isNotNull(noscalePrDaEfPeriodData1)) {
                                if (noscalePrDaEfPeriodData1.getValue() != null){
                                    value = noscalePrDaEfPeriodData1.getValue();
                                }
                            }
                            if (noscalePrDaEfPeriodDataList1.size() > 0) {
                                double valueCount = noscalePrDaEfPeriodDataList1.stream().mapToDouble(NoscalePrDaEfPeriodData::getValue).sum();
                                double b = value / valueCount;
                                generatingcapacity = a * b;
                            }
                        } else if (planpowerDistribution.getType() == 2) {//2为平分
                            Date date1 = DateUtil.beginOfMonth(DateUtil.date());
                            Date date2 = DateUtil.endOfMonth(DateUtil.date());
                            long betweenDay = DateUtil.between(date1, date2, DateUnit.DAY) + 1;
                            generatingcapacity = generatingcapacityCount / betweenDay;
                        }
                        for (Date d : dateList) {
                            String dataTime = DateUtil.format(d, "yyyy-MM-dd HH:mm");
                            ShareController.addMapValue(map, generatingcapacity, dataTime, 3, 4);
                        }
                    }
                }
                /*计划发电量结束*/
            }
        }
        List<DataFormat> dataFormatList = new ArrayList<>();
        String[] nameStr = {"实际发电量", "超短期预测", "短期预测", "计划发电量"};
        int count1 = dateList.size();
        int v = 1;
        for (int i = 0; i < 4; i++) {
            Double[] data = new Double[count1];
            for (int k = 0; k < count1; k++) {
                List<Double> entry = map.get(DateUtil.format(dateList.get(k), "yyyy-MM-dd HH:mm"));
                if (entry != null) {
                    if (entry.size() >= v) {
                        data[k] = entry.get(i);
                    }
                }
            }
            DataFormat dataFormat = new DataFormat();
            dataFormat.setName(nameStr[i]);
            dataFormat.setData(data);
            dataFormatList.add(dataFormat);
            v++;
        }
        json.put("dataFormatList", dataFormatList);
        json.put("dateList", dateList);
        return AjaxResult.success(json);
    }

    @ApiOperation("电量预测-集电线")
    @GetMapping("/electricityForecastJdx")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "唯一主键", required = true),
    })
    public AjaxResult electricityForecastJdx(@RequestParam(value = "id") String id) {
        JSONObject json = new JSONObject();
        //当日的开始时间
        Date beginOfDay = DateUtil.date(DateUtil.beginOfDay(DateUtil.date()).getTime() + 600000);
        //当日的结束时间
        Date endOfDay = DateUtil.date(DateUtil.endOfDay(DateUtil.date()).getTime() + 1000);
        //获取所有时间
        List<Date> dateList = DateTimeUtil.getDateList10(DateUtil.parse(DateUtil.formatDateTime(beginOfDay)), DateUtil.parse(DateUtil.formatDateTime(endOfDay)));
        LinkedMultiValueMap<String, Double> map = new LinkedMultiValueMap<String, Double>();
        Map<String, Object> params = new HashMap<>();
        params.put("beginDataTime", DateUtil.formatDateTime(beginOfDay));
        params.put("endDataTime", DateUtil.formatDateTime(endOfDay));
        String[] ids = id.split("/");
        if (ids.length == 3) {
            Long windplantNo = Convert.toLong(ids[0]);
            Long projectNo = Convert.toLong(ids[1]);
            Long collectorwireNo = Convert.toLong(ids[2]);
            WfFileConfig wfFileConfig = wfFileConfigService.selectWfFileConfigById(windplantNo);
            if (ObjectUtil.isNotNull(wfFileConfig)) {
                /*实际发电量开始*/
                Collectorwireproject collectorwireproject = collectorwireprojectService.selectCollectorwireproject(windplantNo, projectNo, collectorwireNo);
                if (ObjectUtil.isNotNull(collectorwireproject)) {
                    WfYcHistoryData2 wfYcHistoryData2 = new WfYcHistoryData2();
                    wfYcHistoryData2.setAnalogNo(collectorwireproject.getBcrNo());
                    wfYcHistoryData2.setParams(params);
                    List<WfYcHistoryData2> wfYcHistoryData2List = wfYcHistoryData2Service.selectWfYcHistoryData2List(wfYcHistoryData2);
                    for (WfYcHistoryData2 w : wfYcHistoryData2List) {
                        String dataTime = DateUtil.format(w.getDataTime(), "yyyy-MM-dd HH:mm");
                        ShareController.addMapValue(map, w.getYcRawVal(), dataTime, 0, 1);
                    }
                }
                /*实际发电量结束*/
                /*短期预测开始*/
                NoscaleCwDaEfPeriodData noscaleCwDaEfPeriodData = new NoscaleCwDaEfPeriodData();
                noscaleCwDaEfPeriodData.setWfPrCwireNo(collectorwireNo);
                noscaleCwDaEfPeriodData.setModelNo(wfFileConfig.getWpfemodelNo());
                noscaleCwDaEfPeriodData.setParams(params);
                List<NoscaleCwDaEfPeriodData> noscaleCwDaEfPeriodDataList = noscaleCwDaEfPeriodDataService.selectNoscaleCwDaEfPeriodDataList(noscaleCwDaEfPeriodData);
                double countValue = 0;
                for (NoscaleCwDaEfPeriodData n : noscaleCwDaEfPeriodDataList) {
                    String dataTime = DateUtil.format(n.getDataTime(), "yyyy-MM-dd HH:mm");
                    countValue += n.getValue();
                    ShareController.addMapValue(map, countValue, dataTime, 1, 2);
                }
                /*短期预测结束*/
            }
        }
        List<DataFormat> dataFormatList = new ArrayList<>();
        String[] nameStr = {"实际发电量", "短期预测"};
        int count1 = dateList.size();
        int v = 1;
        for (int i = 0; i < 2; i++) {
            Double[] data = new Double[count1];
            for (int k = 0; k < count1; k++) {
                List<Double> entry = map.get(DateUtil.format(dateList.get(k), "yyyy-MM-dd HH:mm"));
                if (entry != null) {
                    if (entry.size() >= v) {
                        data[k] = entry.get(i);
                    }
                }
            }
            DataFormat dataFormat = new DataFormat();
            dataFormat.setName(nameStr[i]);
            dataFormat.setData(data);
            dataFormatList.add(dataFormat);
            v++;
        }
        json.put("dataFormatList", dataFormatList);
        json.put("dateList", dateList);
        return AjaxResult.success(json);
    }

    @ApiOperation("电量预测-风机")
    @GetMapping("/electricityForecastFj")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "唯一主键", required = true),
    })
    public AjaxResult electricityForecastFj(@RequestParam(value = "id") String id) {
        JSONObject json = new JSONObject();
        //当日的开始时间
        Date beginOfDay = DateUtil.date(DateUtil.beginOfDay(DateUtil.date()).getTime() + 600000);
        //当日的结束时间
        Date endOfDay = DateUtil.date(DateUtil.endOfDay(DateUtil.date()).getTime() + 1000);
        //获取所有时间
        List<Date> dateList = DateTimeUtil.getDateList10(DateUtil.parse(DateUtil.formatDateTime(beginOfDay)), DateUtil.parse(DateUtil.formatDateTime(endOfDay)));
        LinkedMultiValueMap<String, Double> map = new LinkedMultiValueMap<String, Double>();
        Map<String, Object> params = new HashMap<>();
        params.put("beginDataTime", DateUtil.formatDateTime(beginOfDay));
        params.put("endDataTime", DateUtil.formatDateTime(endOfDay));
        String[] ids = id.split("/");
        if (ids.length == 4) {
            Long windplantNo = Convert.toLong(ids[0]);
            Long wturNo = Convert.toLong(ids[3]);
            WfFileConfig wfFileConfig = wfFileConfigService.selectWfFileConfigById(windplantNo);
            if (ObjectUtil.isNotNull(wfFileConfig)) {
                /*实际发电量开始*/
                List<Bcr> bcrList = bcrService.selectBcrByWturNo(wturNo);
                if (bcrList.size() > 0) {
                    WfYcHistoryData2 wfYcHistoryData2 = new WfYcHistoryData2();
                    wfYcHistoryData2.setAnalogNo(bcrList.get(1).getBcrNo());
                    wfYcHistoryData2.setParams(params);
                    List<WfYcHistoryData2> wfYcHistoryData2List = wfYcHistoryData2Service.selectWfYcHistoryData2List(wfYcHistoryData2);
                    for (WfYcHistoryData2 w : wfYcHistoryData2List) {
                        String dataTime = DateUtil.format(w.getDataTime(), "yyyy-MM-dd HH:mm");
                        ShareController.addMapValue(map, w.getYcVal(), dataTime, 0, 1);
                    }
                }
                /*实际发电量结束*/
                /*短期预测开始*/
                NoscaleWtgDaEfPeriodData noscaleWtgDaEfPeriodData = new NoscaleWtgDaEfPeriodData();
                noscaleWtgDaEfPeriodData.setWtgNo(wturNo);
                noscaleWtgDaEfPeriodData.setModelNo(wfFileConfig.getWpfemodelNo());
                noscaleWtgDaEfPeriodData.setParams(params);
                List<NoscaleWtgDaEfPeriodData> noscaleWtgDaEfPeriodDataList = noscaleWtgDaEfPeriodDataService.selectNoscaleWtgDaEfPeriodDataList(noscaleWtgDaEfPeriodData);
                double countValue = 0;
                for (NoscaleWtgDaEfPeriodData n : noscaleWtgDaEfPeriodDataList) {
                    String dataTime = DateUtil.format(n.getDataTime(), "yyyy-MM-dd HH:mm");
                    countValue += n.getValue();
                    ShareController.addMapValue(map, countValue, dataTime, 1, 2);
                }
                /*短期预测结束*/
            }
        }
        List<DataFormat> dataFormatList = new ArrayList<>();
        String[] nameStr = {"实际发电量", "短期预测"};
        int count1 = dateList.size();
        int v = 1;
        for (int i = 0; i < 2; i++) {
            Double[] data = new Double[count1];
            for (int k = 0; k < count1; k++) {
                List<Double> entry = map.get(DateUtil.format(dateList.get(k), "yyyy-MM-dd HH:mm"));
                if (entry != null) {
                    if (entry.size() >= v) {
                        data[k] = entry.get(i);
                    }
                }
            }
            DataFormat dataFormat = new DataFormat();
            dataFormat.setName(nameStr[i]);
            dataFormat.setData(data);
            dataFormatList.add(dataFormat);
            v++;
        }
        json.put("dataFormatList", dataFormatList);
        json.put("dateList", dateList);
        return AjaxResult.success(json);
    }

    @ApiOperation("停机设置")
    @GetMapping("/shutdownSettings")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(name = "windplantNo", value = "风场号", required = true),
            @ApiImplicitParam(name = "wturNos", value = "多风机号", required = true),
            @ApiImplicitParam(name = "outageType", value = "停机类型(1计划停机 2非计划停机 3弃风停机 4限电停机)", required = true),
            @ApiImplicitParam(name = "reasonDowntime", value = "停机事由", required = true),
            @ApiImplicitParam(name = "beginDataTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endDataTime", value = "结束时间", required = true),
    })
    public AjaxResult shutdownSettings(@RequestParam(value = "windplantNo") String windplantNo,
                                       @RequestParam(value = "wturNos") String wturNos,
                                       @RequestParam(value = "outageType") String outageType,
                                       @RequestParam(value = "reasonDowntime") String reasonDowntime,
                                       @RequestParam(value = "beginDataTime") String beginDataTime,
                                       @RequestParam(value = "endDataTime") String endDataTime) {
        ThreadContext.bind(manager);
        ThreadUtil.execute(new Runnable() {

            @Override
            public void run() {
                try {
                    Date currentTime = DateUtil.date();
                    List<Date> dateList = DateTimeUtil.getDateList15(DateUtil.parse(beginDataTime), DateUtil.parse(endDataTime));
                    String[] wturNoList = wturNos.split(",");
                    for (String wturNo : wturNoList) {
                        List<WtgStopPlant> wtgStopPlantList = new ArrayList<>();
                        Double ratedPower = wturService.selectWturById(Convert.toLong(wturNo)).getRatedPower();
                        for (Date date : dateList) {
                            WtgStopPlant flag = wtgStopPlantService.selectWtgStopPlant(Convert.toLong(windplantNo), Convert.toLong(wturNo), date);
                            if (ObjectUtil.isNull(flag)) {//为空
                                WtgStopPlant wtgStopPlant = new WtgStopPlant();
                                //风场号
                                wtgStopPlant.setWindplantNo(Convert.toLong(windplantNo));
                                //风机号
                                wtgStopPlant.setWturNo(Convert.toLong(wturNo));
                                //停机时间
                                wtgStopPlant.setDataTime(date);
                                //设置停机时间时间
                                wtgStopPlant.setSetTime(currentTime);
                                //额定功率
                                wtgStopPlant.setRatePower(ratedPower);
                                //是否停机 1停机 0不停机 默认停机
                                wtgStopPlant.setIfstop(Convert.toLong(1));
                                //停机类型
                                wtgStopPlant.setOutageType(Convert.toLong(outageType));
                                //停机事由
                                wtgStopPlant.setReasonDowntime(reasonDowntime);
                                wtgStopPlantList.add(wtgStopPlant);
                            }
                        }
                        if (wtgStopPlantList.size() > 0) {
                            wtgStopPlantService.insertWtgStopPlantList(wtgStopPlantList);
                        }
                    }
                    long endTime = System.currentTimeMillis();
                    System.out.println("批量设置停机程序运行时间：" + (endTime - currentTime.getTime()) + "ms");
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new BusinessException("批量设置停机失败!");
                }
            }
        });
        return AjaxResult.success();
    }

    @ApiOperation("可进行并网设置的停机")
    @GetMapping("/canCarriedOutDowntime")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "唯一主键", required = true),
    })
    public AjaxResult canCarriedOutDowntime(@RequestParam(value = "id") String id) {
        JSONObject json = new JSONObject();
        List<WtgStopPlant> all = new ArrayList<>();
        String[] ids = id.split("/");
        if (ids.length == 1) {//风场
            all.addAll(wtgStopPlantService.selectWtgStopPlantByWindplantNo(Convert.toLong(ids[0]), DateUtil.date()));
        } else if (ids.length == 2) {//期次
            List<WfProjectCwWtg> wfProjectCwWtgList = wfProjectCwWtgService.selectWfProjectCwWtgByPojectNo(Convert.toLong(ids[0]), Convert.toLong(ids[1]));
            for (WfProjectCwWtg wfProjectCwWtg : wfProjectCwWtgList) {
                all.addAll(wtgStopPlantService.selectWtgStopPlantByWturNo(wfProjectCwWtg.getWindplantNo(), wfProjectCwWtg.getWtgNo(), DateUtil.date()));
            }
        } else if (ids.length == 3) {//集电线
            List<WfProjectCwWtg> wfProjectCwWtgList = wfProjectCwWtgService.selectWfProjectCwWtgByCollectorwireNo(Convert.toLong(ids[0]), Convert.toLong(ids[1]), Convert.toLong(ids[2]));
            for (WfProjectCwWtg wfProjectCwWtg : wfProjectCwWtgList) {
                all.addAll(wtgStopPlantService.selectWtgStopPlantByWturNo(wfProjectCwWtg.getWindplantNo(), wfProjectCwWtg.getWtgNo(), DateUtil.date()));
            }
        } else if (ids.length == 4) {//风机
            all.addAll(wtgStopPlantService.selectWtgStopPlantByWturNo(Convert.toLong(ids[0]), Convert.toLong(ids[3]), DateUtil.date()));
        }
        if (all.size() > 0){
            List<WtgStopPlant> wtgStopPlantList = new ArrayList<>();
            Map<Date, List<WtgStopPlant>> allMap = all.stream().collect(Collectors.groupingBy(WtgStopPlant::getSetTime));
            TreeMap<Date, List<WtgStopPlant>> allTreeMap = new TreeMap<Date, List<WtgStopPlant>>(allMap);
            for (Map.Entry<Date, List<WtgStopPlant>> allEntry : allTreeMap.entrySet()) {
                Map<Long, List<WtgStopPlant>> map = allEntry.getValue().stream().collect(Collectors.groupingBy(WtgStopPlant::getWturNo));
                TreeMap<Long, List<WtgStopPlant>> treeMap = new TreeMap<Long, List<WtgStopPlant>>(map);
                for (Map.Entry<Long, List<WtgStopPlant>> entry : treeMap.entrySet()) {
                    WtgStopPlant wtgStopPlant = new WtgStopPlant();
                    wtgStopPlant.setWturNo(entry.getKey());
                    List<WtgStopPlant> list = entry.getValue();
                    if (list.size() > 0) {
                        ListUtil.sortByProperty(list, "dataTime");
                        Map<String, Object> params = new HashMap<>();
                        params.put("beginDataTime", DateUtil.formatDateTime(list.get(0).getDataTime()));
                        params.put("endDataTime", DateUtil.formatDateTime(list.get(list.size() - 1).getDataTime()));
                        wtgStopPlant.setParams(params);
                        wtgStopPlant.setReasonDowntime(list.get(0).getReasonDowntime());
                    }
                    wtgStopPlantList.add(wtgStopPlant);
                }
            }
            List<ConfigurationElement> configurationElementList = new ArrayList<>();
            Map<Map<String, Object>, List<WtgStopPlant>> endMap = wtgStopPlantList.stream().collect(Collectors.groupingBy(WtgStopPlant::getParams));
            int index = 0;
            for (Map.Entry<Map<String, Object>, List<WtgStopPlant>> entry : endMap.entrySet()) {
                ConfigurationElement configurationElement = new ConfigurationElement();
                configurationElement.setName(entry.getKey().get("beginDataTime") + "至" + entry.getKey().get("endDataTime"));
                StringBuilder wturNos = new StringBuilder();
                List<WtgStopPlant> list = entry.getValue();
                if (list.size() > 0) {
                    for (WtgStopPlant w : list) {
                        wturNos.append(w.getWturNo()).append(",");
                    }
                    configurationElement.setContent(list.get(0).getReasonDowntime());
                }
                configurationElement.setId(wturNos.toString().substring(0, wturNos.toString().length() - 1));
                configurationElement.setIndex(index);
                configurationElementList.add(configurationElement);
                index++;
            }
            json.put("list", configurationElementList);
        }
        return AjaxResult.success(json);
    }

    @ApiOperation("并网设置")
    @GetMapping("/gridConnection")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(name = "windplantNo", value = "风场号", required = true),
            @ApiImplicitParam(name = "wturNos", value = "多风机号", required = true),
            @ApiImplicitParam(name = "overhaulResults", value = "维护检查成果", required = true),
            @ApiImplicitParam(name = "beginDataTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endDataTime", value = "结束时间", required = true),
    })
    public AjaxResult gridConnection(@RequestParam(value = "windplantNo") String windplantNo,
                                     @RequestParam(value = "wturNos") String wturNos,
                                     @RequestParam(value = "overhaulResults") String overhaulResults,
                                     @RequestParam(value = "beginDataTime") String beginDataTime,
                                     @RequestParam(value = "endDataTime") String endDataTime) {
        ThreadContext.bind(manager);
        ThreadUtil.execute(new Runnable() {

            @Override
            public void run() {
                try {
                    List<Date> dateList = DateTimeUtil.getDateList15(DateUtil.parse(beginDataTime), DateUtil.parse(endDataTime));
                    String[] wturNoList = wturNos.split(",");
                    for (String wturNo : wturNoList) {
                        for (Date date : dateList) {
                            WtgStopPlant wtgStopPlant = wtgStopPlantService.selectWtgStopPlant(Convert.toLong(windplantNo), Convert.toLong(wturNo), date);
                            if (ObjectUtil.isNotNull(wtgStopPlant)) {//非空
                                //是否停机 1停机 0不停机
                                wtgStopPlant.setIfstop(Convert.toLong(0));
                                //维护检查成果
                                wtgStopPlant.setOverhaulResults(overhaulResults);
                                wtgStopPlantService.updateWtgStopPlant(wtgStopPlant);
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new BusinessException("批量设置不停机失败!");
                }
            }
        });
        return AjaxResult.success();
    }
}
