package com.base.plan.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.base.api.client.*;
import com.base.api.model.*;
import com.base.api.model.request.FzTaskInfoRpcReqDTO;
import com.base.api.model.request.PayloadRpcReqDTO;
import com.base.api.model.request.PointListRpcReqDTO;
import com.base.api.model.request.QueryStationAddRpcDTO;
import com.base.core.StripExecuteInitialize;
import com.base.core.StripTemplate;
import com.base.core.model.enity.*;
import com.base.core.model.enums.StripAccessTypeEnums;
import com.base.core.utiles.ListUtils;
import com.base.orbit.mq.model.BaseHeadMqDTO;
import com.base.orbit.mq.model.enums.MessageTypeEnums;
import com.base.orbit.mq.topics.TopicConst;
import com.base.orbit.utils.BizUtils;
import com.base.orbit.utils.DateUtils;
import com.base.orbit.utils.IdGenerator;
import com.base.orbit.utils.TimeUtil;
import com.base.plan.assembler.EphTrackAssembler;
import com.base.plan.constant.Constants;
import com.base.plan.deal.impl.PointNuaaFileHandler;
import com.base.plan.mapper.*;
import com.base.plan.model.dto.PointDTO;
import com.base.plan.model.dto.StripDTO;
import com.base.plan.model.dto.*;
import com.base.plan.model.dto.request.*;
import com.base.plan.model.entity.*;
import com.base.plan.model.enums.TaskStateEnums;
import com.base.plan.model.input.SarInput;
import com.base.plan.mq.model.*;
import com.base.plan.service.biz.StripBiz;
import com.base.plan.utils.FileUploadUtil;
import com.base.plan.utils.ReadTxtFileTool;
import com.base.task.TaskInitialize;
import com.base.task.cdlatch.aop.Countdlatch;
import com.base.task.core.taskUtils;
import com.base.task.model.Enums.TaskTypeEnum;
import com.base.task.model.Task;
import com.base.task.model.input.SubEphTargetInput;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.plan.api.model.StripRpcDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.*;
import java.math.BigDecimal;
import java.nio.channels.FileChannel;
import java.time.ZoneOffset;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

@Service
@Slf4j
public class StripService extends ServiceImpl<StripMapper, StripInfo> {

    @Resource
    StripMapper stripMapper;
    @Resource
    AlgSchemeStepWindowMapper algSchemeStepWindowMapper;
    @Resource
    PointRpcService pointRpcService;
    @Resource
    PayloadRpcService payloadRpcService;
    @Resource
    StripBiz stripBiz;
    @Resource
    FzTaskRpcService fzTaskRpcService;
    @Resource
    ReadTxtFileTool readTxtFileTool;
    @Resource
    TaskInitialize taskInitialize;
    @Resource
    EphRpcService ephRpcService;
    @Resource
    TrbutDataRpcService trbutDataRpcService;
    @Resource
    StepWindowRelationMapper stepWindowRelationMapper;

    @Value("${exe.filePath}")
    private String filePath;

    @Value("${exe.matFileName}")
    private String matFileName;

    @Value("${expect.coverage}")
    private double expectCoverage;

    @Resource
    ArcService arcService;

    @Resource
    RegionService regionService;

    @Resource
    EphTrackService ephTrackService;

    @Resource
    StripExecuteInitialize stripExecuteInitialize;

    @Resource
    StripTemplate stripAbstractTemplate;

    @Resource
    SatelliteRpcService satelliteRpcService;

    @Resource
    AreaOptimizationResultInfoMapper areaOptimizationResultInfoMapper;

    @Resource
    StationRpcService stationRpcService;

    @Resource
    AlgSchemeWindowPassMapper algSchemeWindowPassMapper;

    @Resource
    StripCalcResultService stripCalcResultService;

//    @Resource
//    StepMqProducer stepMqProducer;


    @Resource
    SubPointDataRpcService subPointDataRpcService;

    @Resource
    SceneBasisTargetRpcService sceneBasisTargetRpcService;

    @Resource
    SceneTargetPointRpcService sceneTargetPointRpcService;

    @Resource
    PointNuaaFileHandler pointNuaaFileHandler;

    @Value("${outputFile.planUploadPath}")
    private String planUploadPath;

    private final static String PRODUCT_ID_ENG = "taskPlanResult";

    private final static String PRODUCT_ID_CHN = "任务规划结果";

    private final static String PRODUCT_FORMAT = "json";

    private final static Integer REGION_TYPE_POINT = 0;

    private final static Integer REGION_TYPE_AREA = 1;

    private final static String STRIP_CALC_RESULT_SUCCEED = "1";

    private final static String STRIP_CALC_RESULT_FAILED = "0";

    //获取CPU核心数
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();

    private static final int COUR_SIZE = CPU_COUNT * 2;

    private static final int MAX_COUR_SIZE = CPU_COUNT * 4;


    public List<StripRpcDTO> getStripInfo(List<String> stripIds) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.in(!CollectionUtils.isEmpty(stripIds), "id", stripIds);
        queryWrapper.eq("is_delete", 1);
        List<StripInfo> list = stripMapper.selectList(queryWrapper);
        return BizUtils.copyEntityToDto(StripRpcDTO.class, list);
    }

    public Boolean areaOptimization(AreOptimizationReqDTO req) {
        try {
            for (String reqId : req.getReqIds()) {
                stripBiz.taskStepStateNotice(reqId, BizTaskStepEnum.AREA_OPTIMIZATION, 0);
            }
            //根据req查询对应条带
            StripDTOListReqDTO stripDTOListReqDTO = new StripDTOListReqDTO();
            stripDTOListReqDTO.setReqIds(req.getReqIds());
            List<StripDTO> stripDTOList = getStripDTOList(stripDTOListReqDTO);
            List<StripDTO> exGridsStripDTOS = upGirdIdsByStripId(stripDTOList);     //  条带赋值网格
            //查询已经优选的任务，已经下发的任务，已经绑定地面站的任务，作为后面互斥的条件
            FzTaskInfoRpcReqDTO fzTaskInfoReqDTO = new FzTaskInfoRpcReqDTO();
            List<String> states = new ArrayList<>();
            states.add(TaskStateEnums.TASK_EXECUTE.toString());
            states.add(TaskStateEnums.TASK_PLANNING.toString());
            states.add(TaskStateEnums.TASK_MAKE_PUBLISH.toString());
            states.add(TaskStateEnums.AREA_OPTIMIZATION.toString());
            fzTaskInfoReqDTO.setSteps(states);
            fzTaskInfoReqDTO.setReqIds(req.getReqIds());
            List<FzTaskRpcDTO> fzTaskDTOList = fzTaskRpcService.getFzTaskDTOList(fzTaskInfoReqDTO);
            if (stripBiz.executeAreaOptimization(exGridsStripDTOS, fzTaskDTOList)) {
                for (String reqId : req.getReqIds()) {
                    stripBiz.taskStepStateNotice(reqId, BizTaskStepEnum.AREA_OPTIMIZATION, 1);
                }
                return Boolean.TRUE;
            } else {
                for (String reqId : req.getReqIds()) {
                    stripBiz.taskStepStateNotice(reqId, BizTaskStepEnum.AREA_OPTIMIZATION, 2);
                }
                return Boolean.FALSE;
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            for (String reqId : req.getReqIds()) {
                stripBiz.taskStepStateNotice(reqId, BizTaskStepEnum.AREA_OPTIMIZATION, 2);
            }
            return Boolean.FALSE;
        }
    }

    public Boolean areaOptimizationup(AreOptimizationReqDTO req) {
        try {
            FileSavePathMqNoticeDTO fileSavePathMqNoticeDTO = new FileSavePathMqNoticeDTO();

            AreaOptimizationMqReqIdResultDTO areaOptimizationMqReqIdResultDTO = new AreaOptimizationMqReqIdResultDTO();
            //  根据需求id查询载荷类型
            FzTaskInfoRpcReqDTO fzTaskInfoRpcReqDTO = new FzTaskInfoRpcReqDTO();
            fzTaskInfoRpcReqDTO.setReqIds(req.getReqIds());
            List<FzTaskRpcDTO> fzTaskInfos = fzTaskRpcService.getFzTaskDTOList(fzTaskInfoRpcReqDTO);

            //根据reqid查询对于优选结果
            AreaOptimizationResultReqDTO areaOptimizationResultReqDTO = new AreaOptimizationResultReqDTO();
            areaOptimizationResultReqDTO.setReqIds(req.getReqIds());
            List<AreaOptimizationResultInfo> areaOptimizationResultInfoList = areaOptimizationResultInfoMapper.selectAreaOptimizationResultInfoList(areaOptimizationResultReqDTO);

            List<AreaOptimizationMqBodyResultDTO> reqs = new ArrayList<>();


            if (!CollectionUtils.isEmpty(areaOptimizationResultInfoList)) {
                Map<String, List<AreaOptimizationResultInfo>> listMap = areaOptimizationResultInfoList.stream().collect(Collectors.groupingBy(AreaOptimizationResultInfo::getReqId));
                listMap.forEach((key, value) -> {
                    AreaOptimizationMqBodyResultDTO areaOptimizationMqBodyResultDTO = new AreaOptimizationMqBodyResultDTO();
                    areaOptimizationMqBodyResultDTO.setReqId(key);

                    List<AreaOptimizationMqResultInfo> areaOptimizationMqResultInfos = new ArrayList<>();
                    for (AreaOptimizationResultInfo a : value) {
                        AreaOptimizationMqResultInfo areaOptimizationMqResultInfo = new AreaOptimizationMqResultInfo();
                        BeanUtils.copyProperties(a, areaOptimizationMqResultInfo);
                        areaOptimizationMqResultInfo.setStripIds(Arrays.asList(a.getStripId().split(",")));

                        //查询条带
                        QueryWrapper<StripInfo> queryWrapper = new QueryWrapper();
                        queryWrapper.in("id", areaOptimizationMqResultInfo.getStripIds());
                        List<StripInfo> stripInfos = this.list(queryWrapper);
                        List<StripInfoMqDTO> stripInfoMqDTOS = BizUtils.copyEntityToDto(StripInfoMqDTO.class, stripInfos);
                        for (StripInfoMqDTO s : stripInfoMqDTOS) {
                            //根据条带时间查询星下点
                            List<SubPointDataRpcDTO> subPointDataList = subPointDataRpcService.getSubPointDataListForTaskUpload(s.getSatelliteCode(), DateUtils.DateToString(s.getObservationStartTime()), DateUtils.DateToString(s.getObservationEndTime()));
                            s.setSubPointDataRpcDTOS(subPointDataList);
                        }
                        areaOptimizationMqResultInfo.setStripInfos(stripInfoMqDTOS);
                        //查询条带点数据
                        PointListRpcReqDTO pointListReqDTOstr = new PointListRpcReqDTO();
                        pointListReqDTOstr.setParentIds(Lists.newArrayList(stripInfos.get(0).getId()));
                        List<PointRpcDTO> pointInfosstr = pointRpcService.getPointDTOList(pointListReqDTOstr);
                        Double lonallstr = 0.0;
                        Double latallstr = 0.0;
                        for (PointRpcDTO p : pointInfosstr) {
                            lonallstr += Double.valueOf(p.getLongitude());
                            latallstr += Double.valueOf(p.getLatitude());
                        }
                        Double lonstr = lonallstr / pointInfosstr.size();
                        Double latstr = latallstr / pointInfosstr.size();
                        areaOptimizationMqResultInfo.setStriplon(lonstr);
                        areaOptimizationMqResultInfo.setStriplat(latstr);

                        //查询目标点
                        PointListRpcReqDTO pointListReqDTO = new PointListRpcReqDTO();
                        pointListReqDTO.setParentIds(Lists.newArrayList(areaOptimizationMqResultInfo.getParentId()));
                        List<PointRpcDTO> pointInfos = pointRpcService.getPointDTOList(pointListReqDTO);
                        Double lonall = 0.0;
                        Double latall = 0.0;
                        for (PointRpcDTO p : pointInfos) {
                            lonall += Double.valueOf(p.getLongitude());
                            latall += Double.valueOf(p.getLatitude());
                        }
                        Double lon = lonall / pointInfos.size();
                        Double lat = latall / pointInfos.size();
                        areaOptimizationMqResultInfo.setLon(lon);
                        areaOptimizationMqResultInfo.setLat(lat);
                        areaOptimizationMqResultInfos.add(areaOptimizationMqResultInfo);
                    }
                    areaOptimizationMqBodyResultDTO.setAreaOptimizations(areaOptimizationMqResultInfos);
                    reqs.add(areaOptimizationMqBodyResultDTO);
                });

                areaOptimizationMqReqIdResultDTO.setReqs(reqs);
                //将消息体生成JSON文件并输出到指定位置
                String taskId = fzTaskInfos.get(0).getTaskId();
                String filename = planUploadPath + taskId + "/taskPlanResult.json";
                ObjectMapper objectMapper = new ObjectMapper();
                byte[] bytes = objectMapper.writeValueAsBytes(areaOptimizationMqReqIdResultDTO);
                FileUploadUtil.outputToFile(bytes, filename);

                //构建kafka消息体中的消息体
                String fileOutputDTOS = buildResult(filename);
                fileSavePathMqNoticeDTO.setBody(fileOutputDTOS);

                //构建消息头
                BaseHeadMqDTO messageHeader = new BaseHeadMqDTO();
                String createTime = DateUtils.dateTimeNow();
//                messageHeader.setCreationTime(createTime);
//                messageHeader.setOriginator("YKSC");
//                messageHeader.setRecipient("JCPT");
                messageHeader.setMessageType(MessageTypeEnums.TASKRESULT.toString());
//                messageHeader.setMessageId(messageHeader.getMessageType() + "_YKSC" + "_" + createTime);
                fileSavePathMqNoticeDTO.setCreationTime(createTime);
                fileSavePathMqNoticeDTO.setOriginator("YKSC");
                fileSavePathMqNoticeDTO.setRecipient("JCPT");
                fileSavePathMqNoticeDTO.setMessageId(messageHeader.getMessageType() + "_YKSC" + "_" + createTime);
//                fileSavePathMqNoticeDTO.setMessageHeader(messageHeader);

                //构建category
                Category category = new Category();
                category.setTaskId(fzTaskInfos.get(0).getTaskId());
                category.setDataClassify("YKCS-GHJGSB");
                fileSavePathMqNoticeDTO.setCategory(category);

                //发送kafka消息
//                stepMqProducer.push(TopicConst.WXPTFZ_XNZB, "data", fileSavePathMqNoticeDTO);
                return true;
            } else {
                return Boolean.FALSE;
            }

        } catch (Exception e) {
            return Boolean.FALSE;
        }
    }

    /**
     * 构建kafka消息体中的result
     *
     * @param filename
     * @return
     */
    private String buildResult(String filename) {
        List<FileOutputDTO> fileOutputDTOS = new ArrayList<>();
        FileOutputDTO fileOutputDTO = new FileOutputDTO();
        fileOutputDTO.setFilePath(filename);
        fileOutputDTO.setProductIdCHN(PRODUCT_ID_CHN);
        fileOutputDTO.setProductIdENG(PRODUCT_ID_ENG);
        fileOutputDTO.setFileFormat(PRODUCT_FORMAT);
        fileOutputDTO.setFileDate(DateUtils.dateTimeNow());
        fileOutputDTOS.add(fileOutputDTO);

        Map<String, List<FileOutputDTO>> fileInfoMap = new HashMap<>();
        fileInfoMap.put("fileInfo", fileOutputDTOS);
        String fileInfoStr = JSON.toJSONString(fileInfoMap);
        return fileInfoStr;
    }

    public List<StripDTO> upGirdIdsByStripId(List<StripDTO> stripDTOList) {
        StripDTOListReqDTO stripDTOListReqDTO1 = new StripDTOListReqDTO();
        List<String> stripIds = stripDTOList.stream().map(StripDTO::getId).collect(Collectors.toList());
        stripDTOListReqDTO1.setIds(stripIds);
        List<StripInfo> stripInfoList = stripMapper.getStripInfoList(stripDTOListReqDTO1);

        Map<String, List<StripInfo>> stripInfoListMap = stripInfoList.stream().collect(Collectors.groupingBy(StripInfo::getId));

        for (StripDTO stripDTO : stripDTOList) {
            if (stripInfoListMap.containsKey(stripDTO.getId())) {
                List<StripInfo> stripInfos = stripInfoListMap.get(stripDTO.getId());
                String gridIds = stripInfos.get(0).getGridIds();
                if (!StringUtils.isEmpty(gridIds)) {
                    stripDTO.setGirdCodeList(Arrays.asList(gridIds.split(Constants.SPECICAL_SYMBOLS)));
                }
            }
        }
        return stripDTOList;
    }

    @Countdlatch(value = TaskTypeEnum.STRIP, step = "TASK_ACCESS_COMPUTE")
    public List<Task<PlanBizInfo>> createSarInput(StripDTOListAddDTO req) {
        try {
            //  查询区域
            PointListRpcReqDTO pointListRpcReqDTO = new PointListRpcReqDTO();
            pointListRpcReqDTO.setPointType(PointTypeEnums.TARGET.toString());
            pointListRpcReqDTO.setParentIds(Lists.newArrayList(req.getTargetId()));
            List<PointRpcDTO> pointRpcDTOS = pointRpcService.getPointDTOList(pointListRpcReqDTO);
            //  构造input对象，创建任务
            List<Task<PlanBizInfo>> tasks = req.getTasks();
            for (int i = 0; i < tasks.size(); i++) {
                //写target配置文件
                if (writeDependFile(i, pointRpcDTOS)) {
                    if (i != 0) {
                        //复制mat文件到其他线程文件夹
                        copyMatFile(i);
                    }
                    Task<PlanBizInfo> task = tasks.get(i);
                    SarInput sarInput = readTxtFileTool.getSarInputByFile(req, task, pointRpcDTOS);
                    Objects.requireNonNull(sarInput, "create sarinput obj by read txt file is fail!!");
                    task.setInput(sarInput);
                    task.setSatelliteName(req.getSatelliteCode());
                    task.setSatelliteCode(req.getSatelliteCode());
                    PlanBizInfo planBizInfo = new PlanBizInfo();
                    planBizInfo.setPayloadId(req.getPayloadId());
                    //这里的parentID为reqID
                    planBizInfo.setParentId(req.getReqIds().get(0));
                    planBizInfo.setPointRpcDTOS(pointRpcDTOS);
                    planBizInfo.setWorkMode(req.getWorkMode());
                    planBizInfo.setSatelliteId(req.getSatelliteId());
                    task.setBaseBizInfo(planBizInfo);
                }
            }
            return tasks;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }

    public void copyMatFile(int i) throws IOException {
        String destfilePath = taskInitialize.FilepathMap.get(TaskTypeEnum.STRIP + "_inppath").get(i);
        File source = new File(filePath + matFileName);
        File dest = new File(destfilePath + matFileName);
        FileChannel inputChannel = null;
        FileChannel outputChannel = null;
        try {
            inputChannel = new FileInputStream(source).getChannel();
            outputChannel = new FileOutputStream(dest).getChannel();
            outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
        } finally {
            inputChannel.close();
            outputChannel.close();
        }

    }

    public boolean writeDependFile(int i, List<PointRpcDTO> pointRpcDTOS) throws IOException {
        String lonlat1 = pointRpcDTOS.get(0).getLongitude() + " " + pointRpcDTOS.get(0).getLatitude();
        String lonlat2 = pointRpcDTOS.get(1).getLongitude() + " " + pointRpcDTOS.get(1).getLatitude();
        String lonlat3 = pointRpcDTOS.get(2).getLongitude() + " " + pointRpcDTOS.get(2).getLatitude();
        String lonlat4 = pointRpcDTOS.get(3).getLongitude() + " " + pointRpcDTOS.get(3).getLatitude();

        SubEphTargetInput subEphTargetInput = new SubEphTargetInput();
        subEphTargetInput.setLonlat1(lonlat1);
        subEphTargetInput.setLonlat2(lonlat2);
        subEphTargetInput.setLonlat3(lonlat3);
        subEphTargetInput.setLonlat4(lonlat4);

        String data = taskUtils.getTaskInputString(subEphTargetInput.getClass(), subEphTargetInput);
        String filePath = taskInitialize.FilepathMap.get(TaskTypeEnum.STRIP + "_targetinppath").get(i);
        String inputdataFileName = taskInitialize.FilepathMap.get(TaskTypeEnum.STRIP + "_targetinpname").get(0);
        File file = new File(filePath + inputdataFileName);
        boolean isDelete = true;
        if (file.exists()) {
            isDelete = file.delete();
        }
        if (isDelete) {
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));
            bufferedWriter.write(data);
            bufferedWriter.flush();
            bufferedWriter.close();
        } else {
            return false;
        }
        return true;

    }


    public List<StripDTO> getStripDTOList(StripDTOListReqDTO req) {
        List<StripInfo> stripInfoList = stripMapper.getStripInfoList(req);
        if (CollectionUtils.isEmpty(stripInfoList)) {
            return new ArrayList<>();
        }
//        List<StripDTO> stripDTOS = BizUtils.copyEntityToDto(StripDTO.class, stripInfoList);
//        PayloadRpcReqDTO payloadRpcReqDTO = new PayloadRpcReqDTO();
//        payloadRpcReqDTO.setPayloadIds(Lists.newArrayList(stripInfoList.stream().map(StripInfo::getPayloadId).collect(Collectors.toSet())));
//        List<PayloadRpcDTO> payloadRpcDTOList = payloadRpcService.getPayloadRpcDTOList(payloadRpcReqDTO);
//        stripDTOS.forEach(e -> {
//            Optional<PayloadRpcDTO> payloadRpcDTOOptional =
//                    payloadRpcDTOList.stream().filter(k -> k.getId().equals(e.getPayloadId())).findFirst();
//            payloadRpcDTOOptional.ifPresent(payloadRpcDTO -> e.setPayloadType(payloadRpcDTO.getPayloadType()));
//            payloadRpcDTOOptional.ifPresent(swathWidth -> e.setSwathWidth(new BigDecimal(swathWidth.getSwathWidth()).toPlainString()));
//        });
        List<StripDTO> stripDTOS = recStripDTO(stripInfoList);
        setPointDTOList(stripDTOS);
        return stripDTOS;
    }

    /**
     * 构建元任务列表
     *
     * @param req
     * @return
     */
    public List<StripReqDTO> selStripDTOList(StripDTOListReqDTO req) {
        List<StripInfo> stripInfoList = stripMapper.getStripInfoList(req);
        if (CollectionUtils.isEmpty(stripInfoList)) {
            return new ArrayList<>();
        }
        List<StripReqDTO> stripReqDTOS = new ArrayList<>();

        Map<String, List<PointRpcDTO>> pointListMap = selPointsByStripIds(stripInfoList);

        //  根据卫星圈号分组
        Map<String, List<StripInfo>> circleMap = stripInfoList.stream().collect(
                Collectors.groupingBy(stripReqDTO ->
                        stripReqDTO.getSatelliteCode() + "-" + stripReqDTO.getCircle(), LinkedHashMap::new, Collectors.toList()));
/*        Map<String, List<StripInfo>> circleMap = stripInfoList.stream().collect(
                Collectors.groupingBy(stripReqDTO ->
                        stripReqDTO.getSatelliteCode()));*/

        for (Map.Entry<String, List<StripInfo>> entry : circleMap.entrySet()) {
            String key = entry.getKey();
            StripReqDTO stripReqDTO = new StripReqDTO();
            String[] keystr = key.split("-");
            String SatelliteCode = "";
            String Circle = "";
            if (keystr.length >= 3) {
                SatelliteCode = keystr[0] + "-" + keystr[1];
                Circle = keystr[2];
            } else {
                SatelliteCode = keystr[0];
                Circle = keystr[1];
            }
            stripReqDTO.setSatelliteCode(SatelliteCode);
            stripReqDTO.setCircle(Circle);
            List<StripInfo> stripInfos = entry.getValue();
            List<StripDTO> stripDTOS = BizUtils.copyEntityToDto(StripDTO.class, stripInfos);

            stripDTOS.stream().forEach(stripDTO -> {
                        //   取中间时刻
                        long time = (stripDTO.getObservationEndTime().getTime() + stripDTO.getObservationStartTime().getTime()) / 2;
                        stripDTO.setAccessTime(new Date(time));
                        stripDTO.setDuration((stripDTO.getObservationEndTime().getTime() - stripDTO.getObservationStartTime().getTime()) / 1000);
                        stripDTO.setCoverageRate(stripDTO.getCoverageRate());

                        if (pointListMap.containsKey(stripDTO.getId())) {
                            stripDTO.setPointDTOList(BizUtils.copyEntityToDto(PointDTO.class, pointListMap.get(stripDTO.getId())));
                        }
                    }
            );
            stripReqDTO.setStripRollAngleDTOS(stripDTOS);
            stripReqDTOS.add(stripReqDTO);
            stripReqDTOS = stripReqDTOS.stream().sorted(Comparator.comparing(StripReqDTO::getSatelliteCode)).collect(Collectors.toList());
        }
        return stripReqDTOS;
    }

    /**
     * 根据条带id查询point
     *
     * @param stripInfoList 条带集合
     * @return
     */
    public Map<String, List<PointRpcDTO>> selPointsByStripIds(List<StripInfo> stripInfoList) {
        //  根据条带id查询point点
        PointListRpcReqDTO pointListReqDTO = new PointListRpcReqDTO();
        pointListReqDTO.setPointType("STRIP");
        pointListReqDTO.setParentIds(stripInfoList.stream().map(StripInfo::getId).collect(Collectors.toList()));
        List<PointRpcDTO> pointInfos = pointRpcService.getPointDTOList(pointListReqDTO);
        pointInfos.sort(Comparator.comparing(e -> Integer.parseInt(e.getSerial())));
        Map<String, List<PointRpcDTO>> pointListMap = pointInfos.stream().collect(Collectors.groupingBy(PointRpcDTO::getParentId));

        return pointListMap;
    }

    public List<AreaOptimizationDTO> getAreaOptimizaPlan(StripDTOListReqDTO req) {
        List<AreaOptimizationDTO> areaOptimizationDTOS = new ArrayList<>();
        AreaOptimizationResultReqDTO areaOptimizationResultReqDTO = new AreaOptimizationResultReqDTO();
        areaOptimizationResultReqDTO.setReqIds(req.getReqIds());
        List<AreaOptimizationResultInfo> areaOptimizationResultInfos = areaOptimizationResultInfoMapper.selectAreaOptimizationResultInfoList(areaOptimizationResultReqDTO);
        if (!CollectionUtils.isEmpty(areaOptimizationResultInfos)) {
            areaOptimizationResultInfos.stream().forEach(areaOptimizationResultInfo -> {
                AreaOptimizationDTO areaOptimizationDTO = new AreaOptimizationDTO();
                BeanUtils.copyProperties(areaOptimizationResultInfo, areaOptimizationDTO);
                areaOptimizationDTO.setIsReScreenSatellite(areaOptimizationDTO.getCoverage() > expectCoverage ? 0 : 1);
                areaOptimizationDTO.setParentType(getParentTypeById(areaOptimizationDTO.getParentId()));
                String stripIds = areaOptimizationResultInfo.getStripId();
                List<String> stripList = Arrays.asList(stripIds.split(","));
                QueryWrapper queryWrapper = new QueryWrapper();
                queryWrapper.in("id", stripList);
                List<StripInfo> stripInfos = this.list(queryWrapper);
                List<StripDTO> stripDTOS = recStripDTO(stripInfos);
                setPointDTOList(stripDTOS);
                stripDTOS.stream().forEach(stripDTO -> {
                    stripDTO.setDuration((stripDTO.getObservationEndTime().getTime() - stripDTO.getObservationStartTime().getTime()) / 1000);
                });
                areaOptimizationDTO.setStripDTOList(stripDTOS.stream().collect(
                        Collectors.groupingBy(stripReqDTO ->
                                stripReqDTO.getSatelliteCode() + "-" + stripReqDTO.getTargetName())));
                areaOptimizationDTOS.add(areaOptimizationDTO);
            });
        }
        return areaOptimizationDTOS;
    }

    public Integer getParentTypeById(String targetId) {
        PointListRpcReqDTO pointListRpcReqDTO = new PointListRpcReqDTO();
        pointListRpcReqDTO.setParentIds(Arrays.asList(targetId));
        List<PointRpcDTO> pointDTOList = pointRpcService.getPointDTOList(pointListRpcReqDTO);
        if (!CollectionUtils.isEmpty(pointDTOList)) {
            return pointDTOList.size() == 1 ? 0 : 1;
        }
        return null;
    }

    public List<StripDTO> recStripDTO(List<StripInfo> stripInfoList) {
        List<StripDTO> stripDTOS = BizUtils.copyEntityToDto(StripDTO.class, stripInfoList);
        PayloadRpcReqDTO payloadRpcReqDTO = new PayloadRpcReqDTO();
        payloadRpcReqDTO.setPayloadIds(Lists.newArrayList(stripInfoList.stream().map(StripInfo::getPayloadId).collect(Collectors.toSet())));
        List<PayloadRpcDTO> payloadRpcDTOList = payloadRpcService.getPayloadRpcDTOList(payloadRpcReqDTO);
        stripDTOS.forEach(e -> {
            Optional<PayloadRpcDTO> payloadRpcDTOOptional =
                    payloadRpcDTOList.stream().filter(k -> k.getId().equals(e.getPayloadId())).findFirst();
            payloadRpcDTOOptional.ifPresent(payloadRpcDTO -> e.setPayloadType(payloadRpcDTO.getPayloadType()));
            payloadRpcDTOOptional.ifPresent(swathWidth -> e.setSwathWidth(new BigDecimal(swathWidth.getSwathWidth()).toPlainString()));
        });
        return stripDTOS;
    }

    public List<SatelliteStripDTO> getSatelliteStripDTOList(StripDTOListReqDTO req) {
        List<SatelliteStripDTO> SatelliteStripDTOList = new ArrayList<>();
        Map<String, List<StripDTO>> stripMap = getStripDTOList(req).stream().collect(Collectors.groupingBy(StripDTO::getSatelliteId));
        for (Map.Entry<String, List<StripDTO>> entry : stripMap.entrySet()) {
            SatelliteStripDTO stripDTO = new SatelliteStripDTO();
            stripDTO.setSatelliteId(entry.getKey());
            stripDTO.setSatelliteCode(entry.getValue().get(0).getSatelliteCode());
            //根据开始时间排序
            entry.getValue().sort(Comparator.comparing(StripDTO::getObservationStartTime));
            //判断条带是否是优选条带
            List<StripDTO> stripDTOS = entry.getValue();
            preferredConfirm(stripDTOS);
            stripDTO.setStripDTOList(stripDTOS);
            SatelliteStripDTOList.add(stripDTO);
        }
        return SatelliteStripDTOList;
    }

    private void preferredConfirm(List<StripDTO> stripDTOS) {
        if (!CollectionUtils.isEmpty(stripDTOS)) {
            for (StripDTO stripDTO : stripDTOS) {
                QueryWrapper<AreaOptimizationResultInfo> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("strip_id", stripDTO.getId());
                AreaOptimizationResultInfo areaOptimizationResultInfo = areaOptimizationResultInfoMapper.selectOne(queryWrapper);
                if (areaOptimizationResultInfo != null) {
                    stripDTO.setPreferred(1);
                }
            }
        }
    }

    private void setPointDTOList(List<StripDTO> list) {
        PointListRpcReqDTO pointListReqDTO = new PointListRpcReqDTO();
        pointListReqDTO.setPointType("STRIP");
        pointListReqDTO.setParentIds(list.stream().map(StripDTO::getId).collect(Collectors.toList()));
        List<PointRpcDTO> pointInfos = pointRpcService.getPointDTOList(pointListReqDTO);
        pointInfos.sort(Comparator.comparing(e -> Integer.parseInt(e.getSerial())));
        Map<String, List<PointRpcDTO>> pointListMap = pointInfos.stream().collect(Collectors.groupingBy(PointRpcDTO::getParentId));
        for (StripDTO stripDTO : list) {
            if (pointListMap.containsKey(stripDTO.getId())) {
                stripDTO.setPointDTOList(BizUtils.copyEntityToDto(PointDTO.class, pointListMap.get(stripDTO.getId())));
            }
        }
    }

    /* @IndicationStep(value = {IndicationStepEnums.KJXJS})*/
    public void stripExecute(StripDTOListAddDTO req) {
        /* getPayloadInfosByReqId(req);*/
    }


/*    public void getPayloadInfosByReqId(StripDTOListAddDTO req) {

        //  根据需求id查询载荷类型
        FzTaskInfoRpcReqDTO fzTaskInfoRpcReqDTO = new FzTaskInfoRpcReqDTO();
        fzTaskInfoRpcReqDTO.setReqIds(req.getReqIds());
        List<FzTaskRpcDTO> fzTaskInfos = fzTaskRpcService.getFzTaskDTOList(fzTaskInfoRpcReqDTO);
        FzTaskRpcDTO fzTaskInfo = fzTaskInfos.get(0);
        log.info("星下点查询开始时间:{}", fzTaskInfo.getStartTime());
        log.info("星下点查询结束时间:{}", fzTaskInfo.getEndTime());

        List<PayloadRpcDTO> payloadInfos = null;
        if (CollectionUtils.isEmpty(fzTaskInfo.getPayloadIdList())) {
            payloadInfos = payloadRpcService.getAllList();
        } else {
            PayloadRpcReqDTO payloadRpcReqDTO = new PayloadRpcReqDTO();
            payloadRpcReqDTO.setPayloadIds(fzTaskInfo.getPayloadIdList());
            payloadInfos = payloadRpcService.getPayloadRpcDTOList(payloadRpcReqDTO);
        }

        payloadInfos.forEach(payloadInfo -> {
            System.out.println("====================循环载荷===================");
            List<PayloadWorkModeRpcDTO> payloadWorkModeRpcDTOS = new ArrayList<>();
            if (payloadInfo.getPayloadWorkModes() != null) {
                payloadWorkModeRpcDTOS = JSONArray.parseArray(payloadInfo.getPayloadWorkModes(), PayloadWorkModeRpcDTO.class);
            }
            payloadInfo.setPayloadWorkModeRpcDTOS(payloadWorkModeRpcDTOS);
            payloadWorkModeRpcDTOS.forEach(payloadWorkModeRpcDTO -> {

                //计算所有工作模式
                *//* if (payloadWorkModeRpcDTO.getWorkMode().equals(fzTaskInfo.getWorkMode())) {*//*
                payloadInfo.setSwathWidth(payloadWorkModeRpcDTO.getSwathWidth());
                payloadInfo.setPayloadWorkModes(payloadWorkModeRpcDTO.getWorkMode());
                Map<String, List<PointRpcDTO>> PointRpcDTOmap = fzTaskInfo.getPointDTOList().stream().collect(Collectors.groupingBy(PointRpcDTO::getParentId));
                PointRpcDTOmap.forEach((key, value) -> {
                    List<BizReq> bizReqs = new ArrayList<>();
                    List<EphTrack> ephdatas = new ArrayList<>();
                    BizReq bizReq = new BizReq();
                    try {
                        */

    /**
     * 1.构建观测区域
     * 2.根据观测区域获取可见星下点数据
     *//*
                        System.out.println("====================构建观测区域===================");
                        Region regionCoreDTO = getRegionCoreDTO(fzTaskInfo, value);
                        if (payloadInfo.getPayloadType().equals("sar")) {
                            if (value.size() == 1) {
                                //设置观测区域类型，0为点目标
                                regionCoreDTO.setAreaorpoint(REGION_TYPE_POINT);
                                regionCoreDTO.setStripExecuteHandler(stripExecuteInitialize.map.get(StripAccessTypeEnums.POINT_SAR));
                            } else {
                                regionCoreDTO.setAreaorpoint(REGION_TYPE_AREA);
                                regionCoreDTO.setStripExecuteHandler(stripExecuteInitialize.map.get(StripAccessTypeEnums.AREA_SAR));
                            }
                        } else if (payloadInfo.getPayloadType().equals("kjg") || payloadInfo.getPayloadType().equals("wg")
                                || payloadInfo.getPayloadType().equals("hw") || payloadInfo.getPayloadType().equals("wb")) {
                            if (value.size() == 1) {
                                regionCoreDTO.setAreaorpoint(REGION_TYPE_POINT);
                                regionCoreDTO.setStripExecuteHandler(stripExecuteInitialize.map.get(StripAccessTypeEnums.POINT_CCD_COMMON));
                                regionCoreDTO.setUpdown(1);
                            } else {
                                regionCoreDTO.setAreaorpoint(REGION_TYPE_AREA);
                                regionCoreDTO.setStripExecuteHandler(stripExecuteInitialize.map.get(StripAccessTypeEnums.AREA_CCD_COMMON));
                                regionCoreDTO.setUpdown(1);
                            }
                        } else if (payloadInfo.getPayloadType().equals("IRS")) {
                            //红外 计算跟普通光学一样  星下点查询降轨 升轨都查
                            regionCoreDTO.setStripExecuteHandler(stripExecuteInitialize.map.get(StripAccessTypeEnums.AREA_CCD_COMMON));
                        } else if (payloadInfo.getPayloadType().equals("ELECTRON")) {
                            System.out.println("====================ELECTRON电子区域===================");
                            //电子区域
                            regionCoreDTO.setStripExecuteHandler(stripExecuteInitialize.map.get(StripAccessTypeEnums.AREA_ELECTRONIC));
                            if (fzTaskInfo.getPointDTOList().size() > 1) {
                                //区域
                                regionCoreDTO.setAreaorpoint(REGION_TYPE_AREA);
                            } else {
                                regionCoreDTO.setAreaorpoint(REGION_TYPE_POINT);
                            }

                        }
                        regionCoreDTO.setBizSerial(req.getReqIds().get(0));
                        bizReq.setRegion(regionCoreDTO);
                        System.out.println("====================查出subPointDataRpcDTOS之前，载荷中卫星编号为" + payloadInfo.getSatelliteCode() + "============================");
                        List<SubPointDataRpcDTO> subPointDataRpcDTOS = regionService.getSubPoint(regionCoreDTO, payloadInfo, fzTaskInfo);
                        System.out.println("====================查出subPointDataRpcDTOS===================" + subPointDataRpcDTOS.size() + "=========");
                        if (!CollectionUtils.isEmpty(subPointDataRpcDTOS)) {
                            *//*EphTrack ephTrack = ephTrackService.convertEphTrack(subPointDataRpcDTOS, payloadInfo, fzTaskInfo);
                            ephdatas.add(ephTrack);*//*
                            List<EphTrack> ephdatasnew = ephTrackService.convertEphTracknew(subPointDataRpcDTOS, payloadInfo, fzTaskInfo);
                            ephdatas.addAll(ephdatasnew);

                        }
                        List<EphTrackCoreDTO> ephTrackCoreDTOS = copyEph(ephdatas);
                        bizReq.setEphTrackCoreDTOs(ephTrackCoreDTOS);
                        bizReqs.add(bizReq);
                        List<com.base.core.model.enity.StripDTO> stripDTOList = stripAbstractTemplate.compute(bizReqs);
                        System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
                        System.out.println("====================计算出结果===================" + stripDTOList.size() + "=========");
                        if (!CollectionUtils.isEmpty(stripDTOList)) {
                            saveStrips(stripDTOList, payloadInfo, req, fzTaskInfo, key, value.get(0));
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
                *//*  }*//*
            });

        });
    }*/
    public void getPayloadInfosByReqId(List<TargetDemandRpcDTO> targetDemandRpcDTOS) {
        if (CollectionUtils.isEmpty(targetDemandRpcDTOS)) return;
        ThreadPoolTaskExecutor threadPoolTaskExecutor = null;
        try {
            threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
            threadPoolTaskExecutor.setCorePoolSize(COUR_SIZE);
            threadPoolTaskExecutor.setMaxPoolSize(MAX_COUR_SIZE);
            threadPoolTaskExecutor.setQueueCapacity(MAX_COUR_SIZE * 2 * 10);
            threadPoolTaskExecutor.setKeepAliveSeconds(60);
            threadPoolTaskExecutor.setThreadNamePrefix("threadExecutor-");
            threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
            threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
            threadPoolTaskExecutor.initialize();
            log.info("线程池初始化成功");
        } catch (Exception e) {
            log.info("初始化线程池失败：{}", e.getMessage());
        }
        List<PayloadRpcDTO> payloadRpcDTOList = payloadRpcService.getAllList();
        ArrayList<StripCalcResult> stripCalcResults = new ArrayList<>();
        AtomicLong primaryKeyGenerator = new AtomicLong(1);
        for (TargetDemandRpcDTO targetRelationDTO : targetDemandRpcDTOS) {
            //遍历需求 就是目标
            //使用目标编号查询目标
//            SceneBasisTargetRpcDTO target = sceneBasisTargetRpcService.getTargetByCode(targetRelationDTO.getTargetCode());
            //使用目标id 查询目标点
//            List<SceneTargetPointRpcDTO> SceneTargetPoints = sceneTargetPointRpcService.getPointListByTargetId(target.getId());
            //  反序列化为卫星列表集合


            log.info("开始计算:{}", System.currentTimeMillis());
            List<SatelliteIdAndPayloadDTO> dtos = satelliteIdCastDTO(targetRelationDTO.getSatelliteSelected());
            threadPoolTaskExecutor.execute(() -> {
                for (SatelliteIdAndPayloadDTO dto : dtos) {
                    //根据卫星id查询载荷
                    List<PayloadRpcDTO> payloadRpcDTOS = payloadRpcDTOList
                            .stream()
                            .filter(t -> t.getSatelliteId().equals(dto.getSatelliteId()))
                            .collect(Collectors.toList());

                    if (!CollectionUtils.isEmpty(payloadRpcDTOS)) {
                        for (PayloadRpcDTO payloadRpcDTO : payloadRpcDTOS) {
    /*                //暂时使用第一个载荷 不知道一个卫星是否确定对应一个载荷
                PayloadRpcDTO payloadRpcDTO = payloadRpcDTOS.get(0);*/
                            //  根据卫星id查询卫星信息
                            //                SatelliteRpcDTO satellite = satelliteRpcService.queryAllSatelliteByIds(Lists.newArrayList(dto.getSatelliteId())).get(0);

                            List<BizReq> bizReqs = new ArrayList<>();
                            List<EphTrack> ephdatas = new ArrayList<>();
                            BizReq bizReq = new BizReq();
                            StripCalcResult stripCalcResult = new StripCalcResult();
                            String stripCalcResultId = UUID.randomUUID().toString().replace("-", "") + primaryKeyGenerator.getAndIncrement();
                            stripCalcResult.setStripCalcResultId(stripCalcResultId);
                            stripCalcResult.setTargetCode(targetRelationDTO.getTargetCode());
                            stripCalcResult.setTargetName(targetRelationDTO.getTargetName());
                            stripCalcResult.setStartTime(targetRelationDTO.getStartTime());
                            stripCalcResult.setEndTime(targetRelationDTO.getEndTime());
                            stripCalcResult.setParentId(targetRelationDTO.getParentId());
                            stripCalcResult.setSatelliteCode(payloadRpcDTO.getSatelliteCode());
                            try {
                                /**
                                 * 1.构建观测区域
                                 * 2.根据观测区域获取可见星下点数据
                                 */
                                Region regionCoreDTO = getRegionCoreDTO(targetRelationDTO.getPointDTOList());

                                if (payloadRpcDTO.getPayloadType().equals("SAR")) {
                                    if (targetRelationDTO.getPointDTOList().size() == 1) {
                                        //设置观测区域类型，0为点目标
                                        regionCoreDTO.setAreaorpoint(REGION_TYPE_POINT);
                                        regionCoreDTO.setStripExecuteHandler(stripExecuteInitialize.map.get(StripAccessTypeEnums.POINT_SAR));
                                    } else {
                                        regionCoreDTO.setAreaorpoint(REGION_TYPE_AREA);
                                        regionCoreDTO.setStripExecuteHandler(stripExecuteInitialize.map.get(StripAccessTypeEnums.AREA_SAR));
                                    }
                                } else if (payloadRpcDTO.getPayloadType().equals("CCD") || payloadRpcDTO.getPayloadType().equals("wg")
                                        || payloadRpcDTO.getPayloadType().equals("IRS") || payloadRpcDTO.getPayloadType().equals("wb")) {
                                    if (targetRelationDTO.getPointDTOList().size() == 1) {
                                        regionCoreDTO.setAreaorpoint(REGION_TYPE_POINT);
                                        regionCoreDTO.setStripExecuteHandler(stripExecuteInitialize.map.get(StripAccessTypeEnums.POINT_CCD_COMMON));
                                        /*regionCoreDTO.setUpdown(1);*/
                                    } else {
                                        regionCoreDTO.setAreaorpoint(REGION_TYPE_AREA);
                                        regionCoreDTO.setStripExecuteHandler(stripExecuteInitialize.map.get(StripAccessTypeEnums.AREA_CCD_COMMON));
                                        /*regionCoreDTO.setUpdown(1);*/
                                    }
                                }/* else if (payloadRpcDTO.getType().equals("IRS")) {
                                //红外 计算跟普通光学一样  星下点查询降轨 升轨都查
                                regionCoreDTO.setStripExecuteHandler(stripExecuteInitialize.map.get(StripAccessTypeEnums.AREA_CCD_COMMON));
                            } */ else if (payloadRpcDTO.getPayloadType().equals("ELECTRON")) {
                                    //电子区域
                                    regionCoreDTO.setStripExecuteHandler(stripExecuteInitialize.map.get(StripAccessTypeEnums.AREA_ELECTRONIC));
                                    if (targetRelationDTO.getPointDTOList().size() > 1) {
                                        //区域
                                        regionCoreDTO.setAreaorpoint(REGION_TYPE_AREA);
                                    } else {
                                        regionCoreDTO.setAreaorpoint(REGION_TYPE_POINT);
                                    }

                                }
                                /*regionCoreDTO.setBizSerial(req.getReqIds().get(0));*/
                                bizReq.setRegion(regionCoreDTO);
                                List<SubPointDataRpcDTO> subPointDataRpcDTOS = regionService.getSubPoint(regionCoreDTO, payloadRpcDTO, targetRelationDTO);
                                if (!CollectionUtils.isEmpty(subPointDataRpcDTOS)) {
                                    /*EphTrack ephTrack = ephTrackService.convertEphTrack(subPointDataRpcDTOS, payloadInfo, fzTaskInfo);
                                    ephdatas.add(ephTrack);*/
                                    List<EphTrack> ephdatasnew = ephTrackService.convertEphTracknew(subPointDataRpcDTOS, payloadRpcDTO);
                                    ephdatas.addAll(ephdatasnew);

                                }
                                List<EphTrackCoreDTO> ephTrackCoreDTOS = copyEph(ephdatas);
                                bizReq.setEphTrackCoreDTOs(ephTrackCoreDTOS);
                                bizReqs.add(bizReq);
                                List<com.base.core.model.enity.StripDTO> stripDTOList = stripAbstractTemplate.compute(bizReqs);
                                if (!CollectionUtils.isEmpty(stripDTOList)) {
                                    //  原有代码一个条带生成一个筹划方案
                                    List<AlgSchemeStepWindow> algSchemeStepWindows = formatAndBatch(stripDTOList, payloadRpcDTO, targetRelationDTO.getParentId());
                                    try {
                                        saveStrips(stripDTOList, payloadRpcDTO, targetRelationDTO.getParentId(), targetRelationDTO.getPointDTOList().get(0));
                                    }catch (Exception e){
                                        stripCalcResult.setIsSucceeded(STRIP_CALC_RESULT_FAILED);
                                        log.info("条带保存失败!");
                                    }
                                    //  条带提供测控、数传列表
                                    insetAlgSchemeWindow(targetRelationDTO, payloadRpcDTO, algSchemeStepWindows);
                                }
                                stripCalcResult.setIsSucceeded(STRIP_CALC_RESULT_SUCCEED);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            stripCalcResults.add(stripCalcResult);
                        }
                    }
                }
                stripCalcResultService.saveBatch(stripCalcResults);
            });
            log.info("结束计算:{}", System.currentTimeMillis());
        }
    }

    /**
     * 根据需求开始结束时间、卫星编码、卫星访问时刻获取该卫星测控、数传列表
     *
     * @param targetRelationDTO 需求对象
     * @return List<AlgSchemeWindowPass> 筹划方案
     */
    public void insetAlgSchemeWindow(TargetDemandRpcDTO targetRelationDTO, PayloadRpcDTO payloadRpcDTO, List<AlgSchemeStepWindow> algSchemeStepWindows) {
        //  因需考虑每个条带都要匹配数传、测控资源，考虑性能先根据卫星code匹配出所有进出站数据，再完成时间段过滤
        List<StripInfo> stripInfos = stripMapper.selectList(new QueryWrapper<>());
        for (AlgSchemeStepWindow algSchemeStepWindow : algSchemeStepWindows) {
            List<AlgSchemeWindowPass> windowPasses = new ArrayList<>();
            List<TrbutDataRpcDTO> allTrbutDataDTOS = new ArrayList<>();
            //  条带访问时刻，成像起始时刻结束时间的中间时刻
            Date accessTime = algSchemeStepWindow.getAccessTime();
            //  1.匹配该条带符合的数传站，过滤条件:数传开始时间->访问时刻+3分钟 数传结束时间->条带观测结束时间+24小时
            Date scStartTime = DateUtils.addMinute(accessTime);
            Date scEndTime = DateUtils.addHour(algSchemeStepWindow.getEndTime());
            String circle = "";
            //  条带与筹划方案为一对一关系，所以通过筹划方案id查询条带以获取该条带圈号
            Optional<StripInfo> stripInfoOptional = stripInfos.stream().filter(stripInfo -> stripInfo.getWindowId().equals(algSchemeStepWindow.getId())).collect(Collectors.toList()).stream().findFirst();
            if (stripInfoOptional.isPresent()) {
                StripInfo stripInfo = stripInfoOptional.get();
                circle = stripInfo.getCircle();
            }
            Assert.isTrue(!Objects.isNull(circle), "条带窗口id[" + algSchemeStepWindow.getId() + "]未查询到圈号");
            //  2.过滤符合时间段可用数传弧段|数传资源圈号挑选策略:数传站圈号大于等于条带的圈号
            CxStationRpcDTO scStationVo = new CxStationRpcDTO();
            scStationVo.setCxStartTime(scStartTime);
            scStationVo.setCxEndTime(scEndTime);
            scStationVo.setMinCircle(circle);
            scStationVo.setCodes(Arrays.asList(algSchemeStepWindow.getSatelliteCode()));
            List<TrbutDataRpcDTO> scTrbutDataDTOS = trbutDataRpcService.selTrButData(scStationVo);
            scTrbutDataDTOS.stream().forEach(scTrbutDataDTO -> scTrbutDataDTO.setType(2));
            //  3.匹配该条带符合的测控站，过滤条件:测控开始时间->条带开始时间的凌晨时刻 测控结束时间->条带访问时刻前一个小时
            Date ckStartTime = DateUtils.zeroTime(algSchemeStepWindow.getStartTime());
            Date ckEndTime = DateUtils.subTime(algSchemeStepWindow.getAccessTime());
            //  4.过滤符合时间段可用测控弧段|测控资源圈号挑选策略:测控站圈号小于等于条带的圈号
            CxStationRpcDTO ckStationVo = new CxStationRpcDTO();
            ckStationVo.setCxStartTime(ckStartTime);
            ckStationVo.setCxEndTime(ckEndTime);
            ckStationVo.setMaxCircle(circle);
            ckStationVo.setCodes(Arrays.asList(algSchemeStepWindow.getSatelliteCode()));
            List<TrbutDataRpcDTO> ckTrbutDataDTOS = trbutDataRpcService.selTrButData(ckStationVo);
            ckTrbutDataDTOS.stream().forEach(ckTrbutDataDTO -> ckTrbutDataDTO.setType(1));
            //  5.满足当前条带可用测控列表\数传列表
            allTrbutDataDTOS.addAll(scTrbutDataDTOS);
            allTrbutDataDTOS.addAll(ckTrbutDataDTOS);
            formatAlgSchemeWindowPass(allTrbutDataDTOS, windowPasses, algSchemeStepWindow);
            //  6.测控\数传列表入库
            if (!CollectionUtils.isEmpty(windowPasses)) {
                algSchemeWindowPassMapper.batchAlgSchemeWindowPass(windowPasses);
            }
        }
    }

    /**
     * 归类站点
     *
     * @param trbutData    可用地面站
     * @param windowPasses 结果
     */
    private void formatAlgSchemeWindowPass(List<TrbutDataRpcDTO> trbutData, List<AlgSchemeWindowPass> windowPasses, AlgSchemeStepWindow algSchemeStepWindow) {
        Set<String> stationIds = trbutData.stream().map(TrbutDataRpcDTO::getStationId).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(stationIds)) {
            return;
        }
        List<QueryStationAddRpcDTO> stationListByStationIdSet = stationRpcService.getStationListByStationIdSet(stationIds);
        if (!ListUtils.isNoE(trbutData)) {
            trbutData.forEach(
                    trbutVo -> {
                        Optional<QueryStationAddRpcDTO> optionalYxInfoBasisStation = stationListByStationIdSet.stream().filter(YxInfoBasisStation -> trbutVo.getStationId().equals(YxInfoBasisStation.getId())).findFirst();
                        if (optionalYxInfoBasisStation.isPresent()) {
                            AlgSchemeWindowPass windowPass = AlgSchemeWindowPass.builder()
                                    .id(IdGenerator.getStrId())
                                    .schemeStepWindowId(algSchemeStepWindow.getId())
                                    .satelliteId(trbutVo.getSatelliteId())
                                    .passNum(trbutVo.getOrbitNum())
                                    .startTime(trbutVo.getReceiveStartTime())
                                    .endTime(trbutVo.getReceiveEndTime())
                                    .stationId(trbutVo.getStationId())
                                    .totalTime(TimeUtil.totalMin(trbutVo.getReceiveStartTime(), trbutVo.getReceiveEndTime()))
                                    //  存在数传数据则状态为1
                                    .passStatus("1")
                                    .stationName(optionalYxInfoBasisStation.get().getStationName())
                                    .stationCode(optionalYxInfoBasisStation.get().getStationCode())
                                    .passType(trbutVo.getType())
                                    .build();
                            windowPasses.add(windowPass);
                        }
                    });
        }
    }

    /**
     * 生成筹划方案
     *
     * @param stripDTOList  条带集合
     * @param payloadRpcDTO 载荷信息
     * @param parentId
     */
    public List<AlgSchemeStepWindow> formatAndBatch(List<com.base.core.model.enity.StripDTO> stripDTOList, PayloadRpcDTO payloadRpcDTO, String parentId) {
        List<AlgSchemeStepWindow> res = new ArrayList<>();
        for (com.base.core.model.enity.StripDTO strip : stripDTOList) {
            AlgSchemeStepWindow algSchemeStepWindow = new AlgSchemeStepWindow();
            algSchemeStepWindow.setId(UUID.randomUUID().toString());
            strip.setWindowId(algSchemeStepWindow.getId());
            //这里还没有生成方案结果，后面筹划的时候再设置
            // AlgSchemeStepWindow.setSchemStepId("");
            algSchemeStepWindow.setWindowFailedReason("");
            algSchemeStepWindow.setCreatedDate(new Date());
            algSchemeStepWindow.setCreatedBy("");
            algSchemeStepWindow.setLastModifiedBy("");
            algSchemeStepWindow.setLastModifiedDate(new Date());
            algSchemeStepWindow.setSatelliteId(payloadRpcDTO.getSatelliteId());
            algSchemeStepWindow.setSatelliteCode(payloadRpcDTO.getSatelliteCode());
            algSchemeStepWindow.setStartTime(strip.getObservationStartTime());
            algSchemeStepWindow.setEndTime(strip.getObservationEndTime());
            algSchemeStepWindow.setSunAngle(strip.getSunAngle());
            algSchemeStepWindow.setParentId(parentId);
            //  条带访问时刻取起始时间段的中间时刻
            algSchemeStepWindow.setAccessTime(DateUtils.getMiddleTime(strip.getObservationStartTime(), strip.getObservationEndTime()));
            algSchemeStepWindow.setResolvingPower(BigDecimal.valueOf(payloadRpcDTO.getGroundResolution()));
            algSchemeStepWindow.setSideSwayValue(BigDecimal.valueOf(strip.getRollAngle()));
            algSchemeStepWindow.setClothWith(BigDecimal.valueOf(payloadRpcDTO.getSwathWidth()));
            algSchemeStepWindow.setRemarkType(0);
            Double coverageRate = strip.getCoverageRate();
            if (Objects.isNull(coverageRate)) {
                coverageRate = 0.0d;
            }
            algSchemeStepWindow.setCoverage(Float.parseFloat(Double.toString(coverageRate)));
            //  todo 俯仰角暂未实现
//            algSchemeStepWindow.setPitchAngle((float) strip.get());
//            algSchemeStepWindowMapper.insert(algSchemeStepWindow);
            res.add(algSchemeStepWindow);
        }
        algSchemeStepWindowMapper.insertBatch(res);
        return res;
    }

    public void saveStrips(List<com.base.core.model.enity.StripDTO> stripDTOList, PayloadRpcDTO payloadRpcDTO, String parentId, PointRpcDTO pointRpcDTO) {
        List<StripInfo> stripInfos = new ArrayList<>();
        List<PointRpcDTO> pointRpcDTOS = new ArrayList<>();
        for (com.base.core.model.enity.StripDTO s : stripDTOList) {
            StripInfo stripInfo = new StripInfo();
            BeanUtils.copyProperties(s, stripInfo);
            //  条带id
            String stripId = String.valueOf(IdGenerator.getId());
            stripInfo.setId(stripId);
            stripInfo.setPayloadId(s.getMaxPayload().getId());
            stripInfo.setGroundResolution(payloadRpcDTO.getGroundResolution());
            stripInfo.setPitchAngle(s.getPitchAngle());
            stripInfo.setWorkMode(payloadRpcDTO.getPayloadWorkModes());
            /*stripInfo.setReqId(req.getReqIds().get(0));*/
            stripInfo.setSatelliteId(payloadRpcDTO.getSatelliteId());
            stripInfo.setSatelliteCode(payloadRpcDTO.getSatelliteCode());
            stripInfo.setTargetName(pointRpcDTO.getParentName());
            stripInfo.setRollAngle(String.valueOf(s.getRollAngle()));
            /*stripInfo.setPriority(fzTaskRpcDTO.getPriority());//优先级*/
            if (s.getCoverageRate() != null) {
                stripInfo.setCoverageRate(String.valueOf(s.getCoverageRate()));
            }
            stripInfo.setParentId(parentId);
            String start = DateUtils.DateToString(stripInfo.getObservationStartTime());
            String end = DateUtils.DateToString(stripInfo.getObservationEndTime());
            List<CalEphRpcDTO> dtos = ephRpcService.selEphDataByFile(stripInfo.getSatelliteCode(), start, end);
            if (!CollectionUtils.isEmpty(dtos)) {
                String cirCle = dtos.get(0).getCirCle();
                stripInfo.setCircle(cirCle);
            }
            stripInfo.setGridIds(org.apache.commons.lang3.StringUtils.join(s.getGridcodelist(), ","));
            SubPoint subPointstart = s.getStartpoint();
            SubPoint subPointend = s.getEndpoint();

            if (payloadRpcDTO.getPayloadType().equals("ELECTRON")) {
                //电子星入库
                pointRpcDTOS = addpointele(pointRpcDTOS, s, stripId);
            } else if (payloadRpcDTO.getPayloadType().equals("kjg") || payloadRpcDTO.getPayloadType().equals("wg")
                    || payloadRpcDTO.getPayloadType().equals("hw") || payloadRpcDTO.getPayloadType().equals("wb")) {
                stripInfo.setObservationStartTime(subPointstart.getDate());
                stripInfo.setObservationEndTime(subPointend.getDate());
                pointRpcDTOS = addpointeleCCD(pointRpcDTOS, s, stripId);
            } else {
                stripInfo.setObservationStartTime(subPointstart.getDate());
                stripInfo.setObservationEndTime(subPointend.getDate());
                //条带不截取 直接去开始和结束点
/*                SubPoint subPointstart =s.getStartpoint();
                SubPoint subPointend = s.getEndpoint();*/
                //条带截取 需要
/*                SubPoint subPointstart = new SubPoint();
                SubPoint subPointend = new SubPoint();
                for (int i = 0; i < s.getVertex_points().size(); i++) {
                    SubPoint subPoint = s.getVertex_points().get(i);
                    if (CollectionUtils.isEmpty(s.getDates())) {
                        subPointstart = subPoint;
                        subPointend = s.getVertex_points().get(s.getVertex_points().size() - 1);
                        break;
                    } else {
                        if (s.getDates().size() == 1) {
                            if (subPoint.getDate().getTime() == s.getDates().get(0).getTime()) {
                                subPointstart = subPoint;
                            }
                            if (subPoint.getDate().getTime() == s.getDates().get(s.getDates().size() - 1).getTime()) {
                                subPointend = s.getVertex_points().get((s.getVertex_points().size() - 1));
                            }
                        } else {
                            if (subPoint.getDate().getTime() == s.getDates().get(0).getTime()) {
                                subPointstart = subPoint;
                            }
                            if (subPoint.getDate().getTime() == s.getDates().get(s.getDates().size() - 1).getTime()) {
                                subPointend = subPoint;
                            }
                        }
                    }
                }*/

                PointRpcDTO pointRpcDTO0 = new PointRpcDTO();
                PointRpcDTO pointRpcDTO1 = new PointRpcDTO();
                PointRpcDTO pointRpcDTO2 = new PointRpcDTO();
                PointRpcDTO pointRpcDTO3 = new PointRpcDTO();
                pointRpcDTO0.setId(String.valueOf(IdGenerator.getId()));
                pointRpcDTO0.setParentId(stripId);
                pointRpcDTO0.setPointType("STRIP");
                pointRpcDTO0.setSerial(String.valueOf(0));
                pointRpcDTO0.setSort(String.valueOf(1));
                pointRpcDTO0.setLongitude(String.valueOf(subPointstart.getLsLon()));
                pointRpcDTO0.setLatitude(String.valueOf(subPointstart.getLsLat()));
                pointRpcDTOS.add(pointRpcDTO0);

                pointRpcDTO1.setId(String.valueOf(IdGenerator.getId()));
                pointRpcDTO1.setParentId(stripId);
                pointRpcDTO1.setPointType("STRIP");
                pointRpcDTO1.setSerial(String.valueOf(1));
                pointRpcDTO1.setSort(String.valueOf(1));
                pointRpcDTO1.setLongitude(String.valueOf(subPointstart.getRsLon()));
                pointRpcDTO1.setLatitude(String.valueOf(subPointstart.getRsLat()));
                pointRpcDTOS.add(pointRpcDTO1);

                pointRpcDTO2.setId(String.valueOf(IdGenerator.getId()));
                pointRpcDTO2.setParentId(stripId);
                pointRpcDTO2.setPointType("STRIP");
                pointRpcDTO2.setSerial(String.valueOf(2));
                pointRpcDTO2.setSort(String.valueOf(1));
                pointRpcDTO2.setLongitude(String.valueOf(subPointend.getRsLon()));
                pointRpcDTO2.setLatitude(String.valueOf(subPointend.getRsLat()));
                pointRpcDTOS.add(pointRpcDTO2);

                pointRpcDTO3.setId(String.valueOf(IdGenerator.getId()));
                pointRpcDTO3.setParentId(stripId);
                pointRpcDTO3.setPointType("STRIP");
                pointRpcDTO3.setSerial(String.valueOf(3));
                pointRpcDTO3.setSort(String.valueOf(1));
                pointRpcDTO3.setLongitude(String.valueOf(subPointend.getLsLon()));
                pointRpcDTO3.setLatitude(String.valueOf(subPointend.getLsLat()));
                pointRpcDTOS.add(pointRpcDTO3);
            }
            stripInfos.add(stripInfo);

        }

        this.saveBatch(stripInfos);
        pointRpcService.addPointList(pointRpcDTOS);
        System.out.println(stripInfos);
    }

    /**
     * 将卫星字符串转为卫星列表集合
     *
     * @param satelliteSelected 卫星列表字符
     * @return
     */
    public List<SatelliteIdAndPayloadDTO> satelliteIdCastDTO(String satelliteSelected) {
        Assert.isTrue(!satelliteSelected.isEmpty(), "该目标不存在选取的卫星列表");
        satelliteSelected = satelliteSelected.replace("\\\\", "");
        try {
            List<SatelliteIdAndPayloadDTO> dtos = JSONArray.parseArray(satelliteSelected, SatelliteIdAndPayloadDTO.class);
            return dtos;
        } catch (Exception e) {
            log.error("卫星列表反序列化失败，错误信息{}", e);
        }
        return null;
    }

    public List<PointRpcDTO> addpointeleCCD(List<PointRpcDTO> pointRpcDTOS, com.base.core.model.enity.StripDTO s, String stripId) {
        int a = 1;
        if (s.getVertex_points().size() > 20) {
            a = s.getVertex_points().size() / 20;
        }
        for (int i = 0; i < s.getVertex_points().size(); i = i + a) {
            PointRpcDTO pointRpcDTO = new PointRpcDTO();
            SubPoint subPoint = new SubPoint();
            if (s.getVertex_points().size() - i < a) {
                subPoint = s.getVertex_points().get(s.getVertex_points().size() - 1);
            } else {
                subPoint = s.getVertex_points().get(i);
            }
            pointRpcDTO.setId(String.valueOf(IdGenerator.getId()));
            pointRpcDTO.setParentId(stripId);
            pointRpcDTO.setPointType("STRIP");
            pointRpcDTO.setSerial(String.valueOf(i));
            pointRpcDTO.setSort(String.valueOf(1));
            pointRpcDTO.setLongitude(String.valueOf(subPoint.getLsLon()));
            pointRpcDTO.setLatitude(String.valueOf(subPoint.getLsLat()));
            pointRpcDTOS.add(pointRpcDTO);

            PointRpcDTO pointRpcDTO1 = new PointRpcDTO();
            /*SubPoint subPoint1 = s.getVertex_points().get(s.getVertex_points().size()-i-1);*/
            pointRpcDTO1.setId(String.valueOf(IdGenerator.getId()));
            pointRpcDTO1.setParentId(stripId);
            pointRpcDTO1.setPointType("STRIP");
            pointRpcDTO1.setSerial(String.valueOf(s.getVertex_points().size() * 2 - i - 1));
            pointRpcDTO1.setSort(String.valueOf(1));
            pointRpcDTO1.setLongitude(String.valueOf(subPoint.getRsLon()));
            pointRpcDTO1.setLatitude(String.valueOf(subPoint.getRsLat()));
            pointRpcDTOS.add(pointRpcDTO1);
        }
       /*int a=s.getVertex_points().size();
        for (int i = s.getVertex_points().size()+s.getVertex_points().size(); i > s.getVertex_points().size(); i--) {
            PointRpcDTO pointRpcDTO = new PointRpcDTO();
            SubPoint subPoint = s.getVertex_points().get(i-s.getVertex_points().size()-1);
            pointRpcDTO.setId(String.valueOf(IdGenerator.getId()));
            pointRpcDTO.setParentId(stripId);
            pointRpcDTO.setPointType("STRIP");
            pointRpcDTO.setSerial(String.valueOf(0));
            pointRpcDTO.setSort(String.valueOf(a));
            a++;
            pointRpcDTO.setLongitude(String.valueOf(subPoint.getRsLon()));
            pointRpcDTO.setLatitude(String.valueOf(subPoint.getRsLat()));
            pointRpcDTOS.add(pointRpcDTO);
        }*/
        return pointRpcDTOS;
    }

    public List<PointRpcDTO> addpointele(List<PointRpcDTO> pointRpcDTOS, com.base.core.model.enity.StripDTO s, String stripId) {
        for (int i = 0; i < s.getVertex_points().size(); i++) {
            PointRpcDTO pointRpcDTO = new PointRpcDTO();
            SubPoint subPoint = s.getVertex_points().get(i);
            pointRpcDTO.setId(String.valueOf(IdGenerator.getId()));
            pointRpcDTO.setParentId(stripId);
            pointRpcDTO.setPointType("STRIP");
            pointRpcDTO.setSerial(String.valueOf(0));
            pointRpcDTO.setSort(String.valueOf(i));
            pointRpcDTO.setLongitude(String.valueOf(subPoint.getLon()));
            pointRpcDTO.setLatitude(String.valueOf(subPoint.getLat()));
            pointRpcDTOS.add(pointRpcDTO);
        }
        return pointRpcDTOS;
    }

    public List<EphTrackCoreDTO> copyEph(List<EphTrack> ephTracks) {
        List<EphTrackCoreDTO> ephTrackCoreDTOS = EphTrackAssembler.INSTANTS.ephTrackCoreDTOSAssembler(ephTracks);


        return ephTrackCoreDTOS;
    }

    public Region getRegionCoreDTO(List<PointRpcDTO> pointDTOList) throws Exception {
        ReportPointCoreDTO reportpoint = new ReportPointCoreDTO();
        //  todo 一个任务有且只有一个观测区域  现在改成多个观测区域

        if (CollectionUtils.isEmpty(pointDTOList)) {
            throw new NullPointerException("目标没有点集合");
        }
        ReportPoint reportPointDTO = arcService.getReportPointDTO(pointDTOList);
        List<ArcCoreDTO> area = arcService.getGridCode(reportPointDTO);
        BeanUtils.copyProperties(reportPointDTO, reportpoint);
        if (CollectionUtils.isEmpty(area)) {
            log.error("error", "Region area is null");
            throw new NullPointerException("Region area is null");
        } else {
            //  用目标最大区域对应的网格列表初始化region
            Region region = regionService.calCRegion(area, reportPointDTO);
            Objects.requireNonNull(region, "region is null");
            /*regionCoreDTO=copyregion(region,regionCoreDTO);*/
            if (pointDTOList.size() > 1) {
                region.setGridlistRegion(pointNuaaFileHandler.totalGird(pointDTOList));
            }
            return region;
        }
    }

/*    public Region getRegionCoreDTO(FzTaskRpcDTO fzTaskRpcDTO, List<PointRpcDTO> pointDTOList) throws Exception {
        ReportPointCoreDTO reportpoint = new ReportPointCoreDTO();
        //  todo 一个任务有且只有一个观测区域  现在改成多个观测区域

        if (CollectionUtils.isEmpty(pointDTOList)) {
            throw new NullPointerException("task id is " + fzTaskRpcDTO.getReqId() + " do not have target!");
        }
        ReportPoint reportPointDTO = arcService.getReportPointDTO(pointDTOList);
        List<ArcCoreDTO> area = arcService.getGridCode(reportPointDTO);
        BeanUtils.copyProperties(reportPointDTO, reportpoint);
        if (CollectionUtils.isEmpty(area)) {
            log.error("error", "Region area is null", fzTaskRpcDTO.getReqId());
            throw new NullPointerException("Region area is null");
        } else {
            //  用目标最大区域对应的网格列表初始化region
            Region region = regionService.calCRegion(area, reportPointDTO);
            Objects.requireNonNull(region, "region is null");
            *//*regionCoreDTO=copyregion(region,regionCoreDTO);*//*
            return region;
        }
    }*/

    public List<CapacityDTO> capacityCount(CapacityReqDTO req) {
        List<CapacityDTO> capacityDTOS = new ArrayList<>();
        StripDTOListReqDTO stripDTOListReqDTO = new StripDTOListReqDTO();
        stripDTOListReqDTO.setIds(req.getIds());
        List<StripInfo> stripInfoList = stripMapper.getStripInfoList(stripDTOListReqDTO);
        log.info("capacityCount sel strip info by reqIds size is " + stripInfoList.size());
        Map<String, List<StripInfo>> stripMap = stripInfoList.stream().collect(Collectors.groupingBy(StripInfo::getSatelliteCode));

        for (Map.Entry<String, List<StripInfo>> entry : stripMap.entrySet()) {
            CapacityDTO capacityDTO = new CapacityDTO();

            String satelliteCode = entry.getKey();
            capacityDTO.setSatelliteCode(satelliteCode);

            List<String> satellitecodes = Lists.newArrayList(satelliteCode);
            List<SatelliteRpcDTO> satelliteRpcDTOList = satelliteRpcService.listByIds(satellitecodes);
            log.info("sel satellite info by satellitecodes size is " + satelliteRpcDTOList.size());
            if (!CollectionUtils.isEmpty(satelliteRpcDTOList)) {
                Optional<SatelliteRpcDTO> satelliteRpcOpt = satelliteRpcDTOList.stream().findFirst();
                if (satelliteRpcOpt.isPresent()) {
                    SatelliteRpcDTO satelliteRpcDTO = satelliteRpcOpt.get();
                    PayloadRpcReqDTO payloadRpcReqDTO = new PayloadRpcReqDTO();
                    payloadRpcReqDTO.setSatelliteCodes(Arrays.asList(satelliteRpcDTO.getSatelliteCode()));
                    List<PayloadRpcDTO> payloadRpcDTOList = payloadRpcService.getPayloadRpcDTOList(payloadRpcReqDTO);
                    PayloadRpcDTO payloadRpcDTO = payloadRpcDTOList.get(0);
                    log.info("sel payload info first vo is " + payloadRpcDTO.toString());
                    capacityDTO.setDataPassSpeed(payloadRpcDTO.getDataPassSpeed()); //  此处应是载荷速率而非卫星对地传输速率 单位:M/s
                    capacityDTO.setBaseMemory(satelliteRpcDTO.getBaseMemory());
                    capacityDTO.setTotalMemory(satelliteRpcDTO.getTotalMemory());
                    List<StripInfo> stripInfos = entry.getValue();
                    double totalSize = 0;
                    for (StripInfo stripInfo : stripInfos) {
                        double count = (stripInfo.getObservationEndTime().getTime() - stripInfo.getObservationStartTime().getTime()) / 1000;
                        totalSize += count * Integer.parseInt(payloadRpcDTO.getDataPassSpeed());
                    }
                    capacityDTO.setBaseMemoryStrip(Double.toString(totalSize / 1024));
                    double baseMemoryStripDb = Double.parseDouble(capacityDTO.getBaseMemoryStrip());
                    double totalMemoryDb = Double.parseDouble(capacityDTO.getTotalMemory());
                    double memortDb = baseMemoryStripDb / totalMemoryDb > 1 ? 1 : baseMemoryStripDb / totalMemoryDb;
                    capacityDTO.setFixedUsage(Double.toString(memortDb));
                    capacityDTO.setFixedVolume(Double.toString(totalMemoryDb - baseMemoryStripDb));//   固存容量=总内存-任务固存占用 单位:M
                    log.info("return capacityDTO info is " + capacityDTO.toString());
                }
                capacityDTOS.add(capacityDTO);
            }
        }
        return capacityDTOS;
    }

    /**
     * 修改条带选中状态\同时确认筹划方案
     *
     * @param list
     */
    public void batchSelectedStrip(List<QuerySelectedStripUpdateDTO> list) {
        List<Long> stripIds = list.stream().map(QuerySelectedStripUpdateDTO::getStripId).collect(Collectors.toList());
//        stripMapper.updateSelectedStatus(list.stream().filter(e -> stripIds.contains(e.getStripId())).collect(Collectors.toList()));
        for (Long stripId : stripIds) {
            StripInfo stripInfo = new StripInfo();
            stripInfo.setId(stripId.toString());
            stripInfo.setIsSelected(2);
            stripMapper.updateById(stripInfo);
        }
        //  todo 确认条带时，还没建立方案与窗口中间表的关系
//        //  条带id就是筹划方案的主键id
//        List<AlgSchemeStepWindow> algSchemeStepWindows = algSchemeStepWindowMapper.selectBatchIds(stripIds);
//        //  根据筹划方案表中的方案评估表的id和筹划方案id修改中间表的确认状态
//        for (AlgSchemeStepWindow algSchemeStepWindow : algSchemeStepWindows) {
//            //  匹配到方案评估Id和筹划方案Id的记录更新确认状态，其他属性不变
//            UpdateWrapper<StepWindowRelation> updateWrapper = new UpdateWrapper<>();
//            updateWrapper.eq("step_id", algSchemeStepWindow.getSchemeStepId());
//            updateWrapper.eq("window_id", algSchemeStepWindow.getId());
//            StepWindowRelation stepWindowRelation = new StepWindowRelation();
//            stepWindowRelation.setIsConfirm(2);
//            stepWindowRelationMapper.update(stepWindowRelation, updateWrapper);
//        }
    }
}