package com.njcn.device.line.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.utils.PubUtils;
import com.njcn.device.biz.pojo.dto.LineALLInfoDTO;
import com.njcn.device.biz.pojo.dto.LineDTO;
import com.njcn.device.biz.pojo.dto.PollutionLineDTO;
import com.njcn.device.biz.pojo.dto.PollutionLineInfoDTO;
import com.njcn.device.biz.pojo.po.Overlimit;
import com.njcn.device.common.mapper.TopMsgMapper;
import com.njcn.device.common.service.GeneralDeviceService;
import com.njcn.device.device.mapper.DeviceMapper;
import com.njcn.device.device.service.PqDevTypeService;
import com.njcn.device.line.mapper.LineMapper;
import com.njcn.device.line.service.DeptLineService;
import com.njcn.device.line.service.LineService;
import com.njcn.device.line.mapper.LineDetailMapper;
import com.njcn.device.biz.mapper.OverlimitMapper;
import com.njcn.device.pq.enums.LineBaseEnum;
import com.njcn.device.pq.enums.PowerFlagEnum;
import com.njcn.device.pq.pojo.dto.GeneralDeviceDTO;
import com.njcn.device.pq.pojo.dto.PollutionParamDTO;
import com.njcn.device.pq.pojo.dto.PollutionSubstationDTO;
import com.njcn.device.pq.pojo.dto.SubstationDTO;
import com.njcn.device.pq.pojo.param.*;
import com.njcn.device.pq.pojo.po.*;
import com.njcn.device.pq.pojo.vo.*;
import com.njcn.device.substation.mapper.SubstationMapper;
import com.njcn.device.subvoltage.mapper.VoltageMapper;
import com.njcn.device.terminal.mapper.TerminalMaintainMapper;
import com.njcn.device.userledger.service.UserLedgerService;
import com.njcn.influx.constant.InfluxDbSqlConstant;
import com.njcn.influx.imapper.PqsCommunicateMapper;
import com.njcn.influx.pojo.po.PqsCommunicate;
import com.njcn.influx.query.InfluxQueryWrapper;
import com.njcn.supervision.pojo.vo.user.NewUserReportVO;
import com.njcn.supervision.pojo.vo.user.UserReportVO;
import com.njcn.system.api.AreaFeignClient;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.pojo.po.Area;
import com.njcn.system.pojo.po.DictData;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.pojo.dto.DeptDTO;
import com.njcn.web.pojo.vo.LineDataVO;
import com.njcn.web.utils.WebUtil;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 监测点类
 *
 * @author denghuajun
 * @date 2022/2/23
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class LineServiceImpl extends ServiceImpl<LineMapper, Line> implements LineService {

    private final AreaFeignClient areaFeignClient;

    private final DicDataFeignClient dicDataFeignClient;

    private final VoltageMapper voltageMapper;

    private final LineDetailMapper lineDetailMapper;

    private final DeviceMapper deviceMapper;

    private final OverlimitMapper overlimitMapper;

    private final SubstationMapper substationMapper;

    private final GeneralDeviceService generalDeviceService;

    private final LineMapper lineMapper;

    private final TopMsgMapper topMsgMapper;

    private final PqsCommunicateMapper pqsCommunicateMapper;

    private final TerminalMaintainMapper terminalMaintainMapper;
    private final DeptFeignClient deptFeignClient;
    private final DeptLineService deptLineService;
    private final UserLedgerService userLedgerService;
    private final PqDevTypeService pqDevTypeService;


    @Override
    public LineDetailDataVO getLineDetailData(String id) {
        if (StringUtils.isEmpty(id)) {
            return new LineDetailDataVO();
        } else {
            //根据id查询当前信息的pids
            List<String> pids = Arrays.asList(this.baseMapper.selectById(id).getPids().split(","));
            List<String> list = new ArrayList(pids);
            list.add(id);
            List<LineDataVO> lineDataVOList = this.baseMapper.getLineDetail(list);
            LineDetailDataVO lineDetailDataVO = new LineDetailDataVO();
            String areaId = "", devId = "", voId = "";
            for (LineDataVO lineDataVO : lineDataVOList) {
                switch (lineDataVO.getLevel()) {
                    case 1:
                        areaId = lineDataVO.getName();
                        break;
                    case 2:
                        lineDetailDataVO.setGdName(lineDataVO.getName());
                        break;
                    case 3:
                        lineDetailDataVO.setBdName(lineDataVO.getName());
                        break;
                    case 4:
                        devId = lineDataVO.getId();
                        lineDetailDataVO.setDevName(lineDataVO.getName());
                        break;
                    case 5:
                        voId = lineDataVO.getId();
                        break;
                    case 6:
                        lineDetailDataVO.setLineName(lineDataVO.getName());
                        break;
                    default:
                        break;
                }
            }
            lineDetailDataVO.setAreaName(areaFeignClient.selectIdArea(areaId).getData().getName());
            lineDetailDataVO.setScale(dicDataFeignClient.getDicDataById(voltageMapper.selectById(voId).getScale()).getData().getName());
            LineDetail lineDetail = lineDetailMapper.selectById(id);
            Device device = deviceMapper.selectById(devId);
            lineDetailDataVO.setManufacturer(dicDataFeignClient.getDicDataById(device.getManufacturer()).getData().getName());
            lineDetailDataVO.setComFlag(PubUtils.comFlag(device.getComFlag()));
            lineDetailDataVO.setRunFlag(PubUtils.lineRunFlag(lineDetail.getRunFlag()));
            lineDetailDataVO.setIp(device.getIp());
            lineDetailDataVO.setLoginTime(device.getLoginTime());
            lineDetailDataVO.setDevId(device.getId());
            lineDetailDataVO.setDevType(device.getDevType());
            lineDetailDataVO.setBusinessType(dicDataFeignClient.getDicDataById(lineDetail.getBusinessType()).getData().getName());
            lineDetailDataVO.setLoadType(dicDataFeignClient.getDicDataById(lineDetail.getLoadType()).getData().getName());
            lineDetailDataVO.setObjId(lineDetail.getObjId());
            lineDetailDataVO.setObjName(lineDetail.getObjName());
            lineDetailDataVO.setId(lineDetail.getNum());
            lineDetailDataVO.setPtType(PubUtils.ptType(lineDetail.getPtType()));
            lineDetailDataVO.setPt(lineDetail.getPt1() + "/" + lineDetail.getPt2());
            lineDetailDataVO.setCt(lineDetail.getCt1() + "/" + lineDetail.getCt2());
            lineDetailDataVO.setDealCapacity(lineDetail.getDealCapacity());
            lineDetailDataVO.setDevCapacity(lineDetail.getDevCapacity());
            lineDetailDataVO.setShortCapacity(lineDetail.getShortCapacity());
            lineDetailDataVO.setStandardCapacity(lineDetail.getStandardCapacity());
            lineDetailDataVO.setTimeInterval(lineDetail.getTimeInterval());
            lineDetailDataVO.setOwner(lineDetail.getOwner());
            lineDetailDataVO.setOwnerDuty(lineDetail.getOwnerDuty());
            lineDetailDataVO.setOwnerTel(lineDetail.getOwnerTel());
            lineDetailDataVO.setWiringDiagram(lineDetail.getWiringDiagram());
            lineDetailDataVO.setPtPhaseType(lineDetail.getPtPhaseType());
            lineDetailDataVO.setUpdateTime(device.getUpdateTime());
            return lineDetailDataVO;
        }

    }



    @Override
    public List<SubstationDetailVO> getSubstationData(List<String> id) {
        return substationMapper.getSubstationData(id);
    }

    @Override
    public CommunicateVO getComFlagInfoData(String id, String searchBeginTime, String searchEndTime) {
        CommunicateVO communicateVOList = new CommunicateVO();
        String devId = lineMapper.getDevIndex(id);
        Device device = deviceMapper.selectById(devId);
        DateTime begin = DateUtil.beginOfDay(DateUtil.parse(searchBeginTime));
        DateTime end = DateUtil.endOfDay(DateUtil.parse(searchEndTime));
        DateTime login = DateUtil.parse(device.getLoginTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
        if (end.isBefore(login)) {
            //结束时间比终端投运时间前，则直接返回空
            return communicateVOList;
        }
        if(begin.isBefore(login)){
            //开始时间大于投运时间，取投运时间
            begin = login;
        }

        List<PqsCommunicate> communicateList = getCommunicate(devId, begin, end);
        List<String> updateTime = new ArrayList<>();
        List<Integer> comType = new ArrayList<>();
        //开始时间
        boolean beginFly = false;
        if (CollUtil.isNotEmpty(communicateList)) {
            if (!communicateList.get(0).getTime().equals(begin.toInstant())) {
                beginFly = true;
            }
        } else {
            beginFly = true;
        }
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (beginFly) {
            Instant instant = begin.toInstant();
            Long time = instant.toEpochMilli();

            String timeText = df.format(time);
            updateTime.add(timeText);
            //取反(正常来时，有变动才会有数据)
            if (CollUtil.isNotEmpty(communicateList)) {
                if (communicateList.get(0).getType() == 0) {
                    comType.add(1);
                } else {
                    comType.add(0);
                }
            } else {
                comType.add(device.getComFlag());
            }

        }
        for (PqsCommunicate communicate : communicateList) {
            //转化时间
            Instant now = communicate.getTime();
            Long time = now.toEpochMilli();
            String timeText = df.format(time);
            updateTime.add(timeText);
            comType.add(communicate.getType());
        }
        //拼接最后时间
        SimpleDateFormat times = new SimpleDateFormat("HH:mm:ss");
        DateTime date = DateTime.now();
        String format = times.format(date);
        Instant endTime = DateUtil.parse(searchEndTime + " " + format).toInstant();

        boolean endFly = false;
        if (CollUtil.isNotEmpty(communicateList)) {
            if (!communicateList.get(communicateList.size() - 1).getTime().equals(endTime)) {
                endFly = true;
            }
        } else {
            endFly = true;
        }
        if (endFly) {
            Long time = endTime.toEpochMilli();
            String timeText = df.format(time);
            updateTime.add(timeText);
            if (CollUtil.isNotEmpty(communicateList)) {
                comType.add(communicateList.get(communicateList.size() - 1).getType());
            } else {
                comType.add(device.getComFlag());
            }
        }
        communicateVOList.setUpdateTime(updateTime);
        communicateVOList.setType(comType);
        return communicateVOList;
    }

    @Override
    public String getLineIdByDevId(String id) {
        //根据id查询当前信息的pids
        List<String> pids = Arrays.asList(this.baseMapper.selectById(id).getPids().split(","));
        List<LineDataVO> lineDataVOList = this.baseMapper.getLineDetail(pids);
        String devId = "";
        for (LineDataVO lineDataVO : lineDataVOList) {
            if (lineDataVO.getLevel() == 4) {
                devId = lineDataVO.getId();
            }
        }
        return devId;
    }

    @Override
    public Set<String> getDevListByLineIdList(List<String> list) {
        Set<String> set = new HashSet<>();
        list.forEach(item->{
            String devId = "";
            //根据id查询当前信息的pids
            List<String> pids = Arrays.asList(this.baseMapper.selectById(item).getPids().split(","));
            List<LineDataVO> lineDataVOList = this.baseMapper.getLineDetail(pids);
            for (LineDataVO lineDataVO : lineDataVOList) {
                if (lineDataVO.getLevel() == 4) {
                    devId = lineDataVO.getId();
                }
            }
            set.add(devId);
        });
        return set;
    }




    @Override
    public PollutionSubstationDTO getSubstationInfo(String id) {
        return this.baseMapper.getSubstationInfo(id);
    }

    @Override
    public List<PollutionLineDTO> getLineInfo(PollutionParamDTO pollutionParamDTO) {
        return this.baseMapper.getLineInfo(pollutionParamDTO.getLineList());
    }

    @Override
    public List<LineDistributionVO> getLineDistribution(DeviceInfoParam deviceInfoParam) {
        List<LineDistributionVO> lineDistributionVOList = new ArrayList<>();
        //获取所有监测点
        List<GeneralDeviceDTO> generalDeviceDTOList = generalDeviceService.getDeviceInfo(deviceInfoParam, Stream.of(0).collect(Collectors.toList()), Stream.of(1).collect(Collectors.toList()));
        for (GeneralDeviceDTO generalDeviceDTO : generalDeviceDTOList) {
            //根据部门id去获取省份信息
            LineDistributionVO lineDistributionVO = new LineDistributionVO();
            lineDistributionVO.setName(generalDeviceDTO.getName());
            lineDistributionVO.setValue(generalDeviceDTO.getLineIndexes().size());
            lineDistributionVOList.add(lineDistributionVO);
        }
        return lineDistributionVOList;
    }


    @Override
    public List<LineStatisticsDetailVO> getLineStatisticsDetail(DeviceInfoParam.BusinessParam deviceInfoParam) {
        List<LineStatisticsDetailVO> lineStatisticsDetailList = new ArrayList<>();
        int deviceAddNumTail = 0, deviceNumTail = 0, lineTail = 0, lineSaveTail = 0, normalStateTail = 0, suspendStateTail = 0, offStreamStateTail = 0, hotSpareStateTail = 0;

        //按照条件获取实际运行终端综合信息
        List<GeneralDeviceDTO> generalDeviceDTOList = generalDeviceService.getDeviceInfo(deviceInfoParam, null, Stream.of(1).collect(Collectors.toList()));
        for (GeneralDeviceDTO generalDeviceDTO : generalDeviceDTOList) {
            LineStatisticsDetailVO lineStatisticsDetail = new LineStatisticsDetailVO();
            // 区域id
            lineStatisticsDetail.setId(generalDeviceDTO.getIndex());
            // 区域/电压等级/干扰源类型/终端厂家
            lineStatisticsDetail.setAreaName(generalDeviceDTO.getName());
            // 区域监测点总数
            lineStatisticsDetail.setLineNum(generalDeviceDTO.getLineIndexes().size());
            // 区域装置总数
            lineStatisticsDetail.setDeviceNum(generalDeviceDTO.getDeviceIndexes().size());
            // 总计装置总数
            deviceNumTail += generalDeviceDTO.getDeviceIndexes().size();
            // 总计监测点总数
            lineTail += generalDeviceDTO.getLineIndexes().size();
            if (generalDeviceDTO.getLineIndexes().size() > 0) {
                //获取监测点新增数
                QueryWrapper<Line> lineQueryWrapper = new QueryWrapper<>();
                lineQueryWrapper.in("pq_line.id", generalDeviceDTO.getLineIndexes());
                lineQueryWrapper.between("pq_line.Create_Time",
                        DateUtil.beginOfDay(DateUtil.parse(deviceInfoParam.getSearchBeginTime())),
                        DateUtil.endOfDay(DateUtil.parse(deviceInfoParam.getSearchEndTime())));
                int countNum = lineMapper.selectCount(lineQueryWrapper);
                lineSaveTail += countNum;
                // 监测点新增数
                lineStatisticsDetail.setAddLineNum(countNum);

                // 获取装置新增数量
                QueryWrapper<Line> deviceQueryWrapper = new QueryWrapper<>();
                deviceQueryWrapper.in("pq_line.id", generalDeviceDTO.getDeviceIndexes());
                deviceQueryWrapper.between("pq_line.Create_Time",
                        DateUtil.beginOfDay(DateUtil.parse(deviceInfoParam.getSearchBeginTime())),
                        DateUtil.endOfDay(DateUtil.parse(deviceInfoParam.getSearchEndTime())));
                int deviceAddNum = lineMapper.selectCount(deviceQueryWrapper);
                deviceAddNumTail += deviceAddNum;
                lineStatisticsDetail.setAddDeviceNum(deviceAddNum);

                LineStateVO lineStateVO;
                //获取状态
                // lineStateVO = lineMapper.getLineStatisticsDetail(generalDeviceDTO.getLineIndexes());
                lineStateVO = lineMapper.getDeviceStatus(generalDeviceDTO.getDeviceIndexes());
                BeanUtil.copyProperties(lineStateVO, lineStatisticsDetail);
                normalStateTail += lineStateVO.getNormalStateNum();
                suspendStateTail += lineStateVO.getSuspendStateNum();
                offStreamStateTail += lineStateVO.getOffStreamStateNum();
                hotSpareStateTail += lineStateVO.getHotSpareStateNum();
            } else {
                lineStatisticsDetail.setAddLineNum(0);
                lineStatisticsDetail.setHotSpareStateNum(0);
                lineStatisticsDetail.setOffStreamStateNum(0);
                lineStatisticsDetail.setNormalStateNum(0);
                lineStatisticsDetail.setSuspendStateNum(0);
                lineStatisticsDetail.setAddDeviceNum(0);
            }
            lineStatisticsDetailList.add(lineStatisticsDetail);
        }
        LineStatisticsDetailVO lineStatisticsDetailVO = new LineStatisticsDetailVO();
        lineStatisticsDetailVO.setAreaName("总计");
        lineStatisticsDetailVO.setAddDeviceNum(deviceAddNumTail);
        lineStatisticsDetailVO.setDeviceNum(deviceNumTail);
        lineStatisticsDetailVO.setLineNum(lineTail);
        lineStatisticsDetailVO.setAddLineNum(lineSaveTail);
        lineStatisticsDetailVO.setNormalStateNum(normalStateTail);
        lineStatisticsDetailVO.setSuspendStateNum(suspendStateTail);
        lineStatisticsDetailVO.setHotSpareStateNum(hotSpareStateTail);
        lineStatisticsDetailVO.setOffStreamStateNum(offStreamStateTail);
        lineStatisticsDetailList.add(lineStatisticsDetailVO);
        int i = 1;
        for (LineStatisticsDetailVO statisticsDetailVO : lineStatisticsDetailList) {
            statisticsDetailVO.setOrderNo(i);
            i++;
        }
        return lineStatisticsDetailList;
    }

    @Override
    public List<LineStatisticsTableVO> getLineStatisticsTable(DeviceInfoParam.BusinessParam deviceInfoParam) {
        List<LineStatisticsTableVO> lineStatisticsTableList = new ArrayList<>();
        List<GeneralDeviceDTO> generalDeviceDTOList = generalDeviceService.getDeviceInfo(deviceInfoParam, null, Stream.of(1).collect(Collectors.toList()));
        for (GeneralDeviceDTO generalDeviceDTO : generalDeviceDTOList) {
            List<String> lineIndexes = generalDeviceDTO.getLineIndexes();
            if (CollectionUtils.isEmpty(lineIndexes)) {
                continue;
            }
            LineStatisticsTableVO lineStatisticsTableVO = new LineStatisticsTableVO();
            lineStatisticsTableVO.setId(generalDeviceDTO.getIndex());
            lineStatisticsTableVO.setName(generalDeviceDTO.getName());
            //组装父级数据树
            List<LineStatisticsTableVO> treeList = getTreeData(lineIndexes, deviceInfoParam);
            lineStatisticsTableVO.setChildren(treeList);
            lineStatisticsTableList.add(lineStatisticsTableVO);
        }
        return lineStatisticsTableList;
    }

    @Override
    public Page<LineFlowMealDetailVO> getNewDeviceRunStatistics(PqsParam deviceInfoParam) {
        List<String> deviceIndexes = new ArrayList<>();
        List<GeneralDeviceDTO> deviceInfoList = generalDeviceService.getDeviceInfo(deviceInfoParam, null, Stream.of(1).collect(Collectors.toList()));
        deviceInfoList.stream().map(GeneralDeviceDTO::getDeviceIndexes).forEach(deviceIndexes::addAll);
        Page<LineFlowMealDetailVO> page = lineMapper.getNewDeviceRunStatistics(
                new Page(deviceInfoParam.getPageNum(), deviceInfoParam.getPageSize()),
                deviceIndexes,
                DateUtil.beginOfDay(DateUtil.parse(deviceInfoParam.getSearchBeginTime())),
                DateUtil.endOfDay(DateUtil.parse(deviceInfoParam.getSearchEndTime())));
        return page;
    }

    @Override
    public Page<TopMsgPO> dailyDeviceAbnormalStatistics(PqsParam param) {
        Page topMsg = topMsgMapper.dailyDeviceAbnormalStatistics(
                new Page(param.getPageNum(), param.getPageSize()),
                param.getLineGrade(),
                DateUtil.beginOfDay(DateUtil.parse(param.getSearchBeginTime())),
                DateUtil.endOfDay(DateUtil.parse(param.getSearchEndTime())));
        return topMsg;
    }

    @Override
    public List<TopMsgPO> dailyDeviceAbnormal(DeviceInfoParam.BusinessParam param) {
        List<TopMsgPO> topMsgDetails = topMsgMapper.dailyDeviceAbnormal(
                param.getLineGrade(),
                DateUtil.beginOfDay(DateUtil.parse(param.getSearchBeginTime())));
        return topMsgDetails;
    }

    @Override
    public Page<HalfReportVO> halfReport(TerminalMainQueryParam param) {
        List<String> ids = new ArrayList<>();
        if (StrUtil.isNotBlank(param.getOrgId())) {
            List<DeptDTO> data = deptFeignClient.getDeptDescendantIndexes(param.getOrgId(), WebUtil.filterDeptType()).getData();
            ids.addAll(data.stream().map(DeptDTO::getId).collect(Collectors.toList()));
        }
        Page<LineMarkVO> page = new Page<>(param.getPageNum(), param.getPageSize());
        param.setSearchBeginTime(DateUtil.beginOfDay(DateUtil.parse(param.getSearchBeginTime())).toString());
        param.setSearchEndTime(DateUtil.endOfDay(DateUtil.parse(param.getSearchEndTime())).toString());
        return this.baseMapper.selectHalfReport(page, param, ids);
    }

    @Override
    public LineDTO getLineDetail(String id) {
        List<DictData> data = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_VOLTAGE_STAND.getCode()).getData();
        Map<String, String> dicMap = data.stream().collect(Collectors.toMap(DictData::getId, DictData::getValue));
        LineDTO lineDTO = this.baseMapper.selectLineDetail(id);
        if (lineDTO != null) {
            if (dicMap.containsKey(lineDTO.getVoltageLevel())) {
                lineDTO.setVoltageLevel(dicMap.get(lineDTO.getVoltageLevel()));
                return lineDTO;
            }
        }
        return null;
    }

    /**
     * 批量根据监测点id获取监测点信息
     */
    @Override
    public List<LineDTO> getLineDetailBatch(List<String> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return null;
        }
        List<LineDTO> lineDTOS = this.baseMapper.selectLineDetailBatch(ids);
        //电压等级
        Map<String, List<LineDTO>> lineVoltageMap = lineDTOS.stream().collect(Collectors.groupingBy(LineDTO::getVoltageLevel));
        List<DictData> voltageList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_VOLTAGE_STAND.getCode()).getData();
        Map<String, String> voltageMap = voltageList.stream().collect(Collectors.toMap(DictData::getId, DictData::getValue));
        lineVoltageMap.forEach((key, lineData) -> {
            String voltage = voltageMap.get(key);
            lineData = lineData.stream().peek(line -> line.setVoltageLevel(voltage)).collect(Collectors.toList());
        });
        return lineDTOS;
    }

    @Override
    public List<LineDetailVO.Detail> getLineDetailByIds(List<String> ids) {
        List<LineDetailVO.Detail> details = this.baseMapper.selectByIds(ids);
        if (CollUtil.isNotEmpty(details)) {
            List<String> devIds = details.stream().map(LineDetailVO.Detail::getDevId).distinct().collect(Collectors.toList());
            //获取终端流量信息
            List<LineFlowMealDetailVO> flow = terminalMaintainMapper.getMonthFlow(devIds, DateUtil.beginOfMonth(DateUtil.date()), DateUtil.endOfMonth(DateUtil.date()));
            Map<String, LineFlowMealDetailVO> flowMap = flow.stream().collect(Collectors.toMap(LineFlowMealDetailVO::getId, Function.identity()));
            //获取行政区域
            List<String> areaIds = details.stream().map(LineDetailVO.Detail::getAreaId).distinct().collect(Collectors.toList());
            List<Area> data = areaFeignClient.areaNameByList(areaIds).getData();
            Map<String, String> areaMap = data.stream().collect(Collectors.toMap(Area::getId, Area::getName));
            //获取电压字典
            List<DictData> dictType = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_VOLTAGE_STAND.getCode()).getData();
            Map<String, String> dictMap = dictType.stream().collect(Collectors.toMap(DictData::getId, DictData::getName));
            //获取终端等级
            List<DictData> gradeType = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_GRADE.getCode()).getData();
            Map<String, Integer> gradeMap = gradeType.stream().collect(Collectors.toMap(DictData::getId, DictData::getAlgoDescribe));
            //获取厂家
            List<DictData> manufacturerType = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_MANUFACTURER.getCode()).getData();
            Map<String, String> manufacturerMap = manufacturerType.stream().collect(Collectors.toMap(DictData::getId, DictData::getName));

            for (LineDetailVO.Detail detail : details) {
                //获取行政区域名称
                if (areaMap.containsKey(detail.getAreaId())) {
                    detail.setAreaName(areaMap.get(detail.getAreaId()));
                }
                //电压
                if (dictMap.containsKey(detail.getVoltageLevel())) {
                    detail.setVoltageLevel(dictMap.get(detail.getVoltageLevel()));
                }
                //终端等级
                if (gradeMap.containsKey(detail.getLineGrade())) {
                    detail.setLineGrade(String.valueOf(gradeMap.get(detail.getLineGrade())));
                }
                //终端等级
                if (flowMap.containsKey(detail.getDevId())) {
                    LineFlowMealDetailVO flowVo = flowMap.get(detail.getDevId());
                    detail.setFlowMeal(flowVo.getFlowMeal());
                    detail.setStatisValue(flowVo.getStatisValue());
                    detail.setFlowProportion(flowVo.getFlowProportion() * 100);
                }
                //厂家
                if (manufacturerMap.containsKey(detail.getManufacturer())) {
                    detail.setManufacturer(manufacturerMap.get(detail.getManufacturer()));
                }
            }
        }
        return details;
    }

    @Override
    public LineALLInfoDTO getLineAllDetail(String id) {
        LineALLInfoDTO lineALLInfoDTO = new LineALLInfoDTO();
        //根据id查询当前信息的pids
        List<String> pids = Arrays.asList(this.baseMapper.selectById(id).getPids().split(","));
        List<String> list = new ArrayList(pids);
        list.add(id);
        List<LineDataVO> lineDataVOList = this.baseMapper.getLineDetail(list);
        LineDetailDataVO lineDetailDataVO = new LineDetailDataVO();

        String areaId = "", gdId = "", subStationId = "", devId = "", voId = "", lineId = "",
                areaName = "", gdName = "", subStationName = "", devName = "", voName = "", lineName = "";
        for (LineDataVO lineDataVO : lineDataVOList) {
            switch (lineDataVO.getLevel()) {
                case 1:
                    areaId = lineDataVO.getId();
                    areaName = lineDataVO.getName();
                    break;
                case 2:
                    gdId = lineDataVO.getId();
                    gdName = lineDataVO.getName();
                    break;
                case 3:
                    subStationId = lineDataVO.getId();
                    subStationName = lineDataVO.getName();
                    break;
                case 4:
                    devId = lineDataVO.getId();
                    devName = lineDataVO.getName();
                    break;
                case 5:
                    voId = lineDataVO.getId();
                    voName = lineDataVO.getName();
                    break;
                case 6:
                    lineId = lineDataVO.getId();
                    lineName = lineDataVO.getName();
                    break;
                default:
                    break;
            }
        }

        LineDetail lineDetail = lineDetailMapper.selectById(id);
        Voltage voltage = voltageMapper.selectById(voId);
        Device device = deviceMapper.selectById(devId);
        Substation substation = substationMapper.selectById(subStationId);
        //处理监测点信息
        LineALLInfoDTO.LineLineDTO lineLineDTO = new LineALLInfoDTO.LineLineDTO();
        lineLineDTO.setLineId(lineId);
        lineLineDTO.setLinename(lineName);
        lineLineDTO.setNum(lineDetail.getNum());
        lineLineDTO.setObjName(lineDetail.getObjName());
        lineLineDTO.setObjId(lineDetail.getObjId());
        if(StringUtils.isNotEmpty(lineDetail.getObjId())){
            UserReportVO userReportVO = userLedgerService.getUserReportById(lineDetail.getObjId());
            lineLineDTO.setObjName2(userReportVO.getProjectName());
        }
        lineLineDTO.setLoadType(dicDataFeignClient.getDicDataById(lineDetail.getLoadType()).getData().getName());
        //电压使用母线电压
        lineLineDTO.setVoltageLevel(dicDataFeignClient.getDicDataById(voltage.getScale()).getData().getName());
        lineALLInfoDTO.setLineLineDTO(lineLineDTO);
        //处理母线信息
        LineALLInfoDTO.LineBusbarDTO lineBusbarDTO = new LineALLInfoDTO.LineBusbarDTO();
        lineBusbarDTO.setBusBarId(voId);
        lineBusbarDTO.setBusBarName(voName);
        lineALLInfoDTO.setLineBusbarDTO(lineBusbarDTO);
        //处理设备信息
        LineALLInfoDTO.LineDeviceDTO lineDeviceDTO = new LineALLInfoDTO.LineDeviceDTO();
        lineDeviceDTO.setDeviceId(devId);
        lineDeviceDTO.setDeviceName(devName);
        lineALLInfoDTO.setLineDeviceDTO(lineDeviceDTO);
        //处理电站信息
        LineALLInfoDTO.LineSubStationDTO lineSubStationDTO = new LineALLInfoDTO.LineSubStationDTO();
        lineSubStationDTO.setSubStationId(subStationId);
        lineSubStationDTO.setSubStationName(subStationName);

        lineALLInfoDTO.setLineSubStationDTO(lineSubStationDTO);
        //todo 处理部门信息后续需要部门信息在添加

        return lineALLInfoDTO;
    }

    @Override
    public DeviceVO getDeviceDetailData(String id) {
        return this.baseMapper.getDeviceDetailData(id);
    }

    @Override
    public List<Line> getSubIndexLineDetail(String id) {
        return this.lambdaQuery()
                .eq(Line::getLevel, 6)
                .like(Line::getPids, id)
                .list();
    }

    @Override
    public List<LineALLInfoDTO> getLineAllDetailList(List<String> ids) {
        List<LineALLInfoDTO> collect = ids.stream().map(this::getLineAllDetail).collect(Collectors.toList());
        return collect;
    }

    @Override
    public List<LineDetailVO.Detail> getDeptDeviceDetailData(DataParam param) {
        List<String> ids = deptFeignClient.getDepSonIdtByDeptId(param.getOrgId()).getData();
        List<DeptLine> deptLines = deptLineService.selectDeptBindLines(ids);
        List<String> lineIDs = deptLines.stream().map(DeptLine::getLineId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(lineIDs)) {
            return this.baseMapper.getDeptDeviceDetailData(lineIDs, param.getSearchValue(), param.getType());
        }
        return new ArrayList<>();
    }

    @Override
    public List<LineDetailVO.noDataLineInfo> getNoDataLine() {
        String time = DateUtil.format(LocalDateTime.now(), DatePattern.NORM_DATE_PATTERN);
        return this.baseMapper.getNoDataLine(time);
    }

    @Override
    public List<ReportLineInfoVo> getReportLineInfo(List<String> ids) {
        return this.baseMapper.getReportLineInfo(ids);
    }

    @Override
    public List<LineDetail> getByName(LineBaseQueryParam param) {
        return this.baseMapper.selectByName(param);
    }

    @Override
    public List<DevAndLine> getByDeptDevLine(String id) {
        List<DevAndLine> info = new ArrayList<>();
        List<String> ids = deptFeignClient.getDepSonIdtByDeptId(id).getData();
        List<DeptLine> deptLines = deptLineService.selectDeptBindLines(ids);
        List<String> lineIDs = deptLines.stream().map(DeptLine::getLineId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(lineIDs)) {
            List<LineDetailVO.Detail> deptDeviceDetailData = this.baseMapper.getDeptDeviceDetailData(lineIDs, null, 3);
            if (CollUtil.isNotEmpty(deptDeviceDetailData)) {
                Map<String, List<LineDetailVO.Detail>> collect = deptDeviceDetailData.stream().collect(Collectors.groupingBy(LineDetailVO.Detail::getDevId));
                collect.forEach((k, v) -> {
                    DevAndLine devAndLine = new DevAndLine();
                    List<DevAndLine.Line> lineList = new ArrayList<>();
                    devAndLine.setDevId(k);
                    devAndLine.setDevName(v.get(0).getDevName());
                    v.stream().distinct().forEach(v1 -> {
                        DevAndLine.Line line = new DevAndLine.Line();
                        line.setLineId(v1.getLineId());
                        line.setLineName(v1.getLineName());
                        lineList.add(line);
                    });
                    devAndLine.setLineList(lineList);
                    info.add(devAndLine);
                });
            }
        }
        return info;
    }

    @Override
    public List<String> getLevelMonitorByDept(String level, String deptId) {
        List<String> deptIds = deptFeignClient.getDepSonIdtByDeptId(deptId).getData();
        List<String> lineIds = deptLineService.list(new LambdaQueryWrapper<DeptLine>().in(DeptLine::getId, deptIds)).stream().map(DeptLine::getLineId).distinct().collect(Collectors.toList());
        List<String> result = lineDetailMapper.selectList(new LambdaQueryWrapper<LineDetail>().select(LineDetail::getId).in(LineDetail::getId, lineIds).eq(LineDetail::getLineGrade, level)).stream().map(LineDetail::getId).distinct().collect(Collectors.toList());
        return result;
    }

    @Override
    public List<LineDetail> getMonitorByObjId(String objId) {
        List<LineDetail> result;
        result = lineDetailMapper.selectList(new LambdaQueryWrapper<LineDetail>().eq(LineDetail::getObjId, objId));
        if (CollUtil.isNotEmpty(result)) {
            List<String> ids = result.stream().map(LineDetail::getId).distinct().collect(Collectors.toList());
            List<Line> lineList = lineMapper.selectList(new LambdaQueryWrapper<Line>().in(Line::getId, ids).eq(Line::getState, DataStateEnum.ENABLE.getCode()));
            Map<String, Line> lineMap = lineList.stream().collect(Collectors.toMap(Line::getId, Function.identity()));
            result.forEach(item -> item.setMonitorName(lineMap.getOrDefault(item.getId(), new Line()).getName()));
        }
        return result;
    }

    @Override
    public List<PollutionSubstationDTO> getPowerStationByMonitorIds(List<String> ids) {
        List<PollutionSubstationDTO> result = new ArrayList<>();
        List<LineDetail> lineDetailList = lineDetailMapper.selectList(new LambdaQueryWrapper<LineDetail>().in(LineDetail::getId, ids));
        List<LineDetail> userLedgerList = lineDetailList.stream().filter(it -> StrUtil.isNotBlank(it.getObjId())).collect(Collectors.toList());
        List<LineDetail> powerLedgerList = lineDetailList.stream().filter(it -> StrUtil.isBlank(it.getObjId())).collect(Collectors.toList());

        if (CollUtil.isNotEmpty(userLedgerList)) {
            List<String> objIds = userLedgerList.stream().map(LineDetail::getObjId).distinct().collect(Collectors.toList());
            List<NewUserReportVO> newUserReportVOList = userLedgerService.getUserReportByIds(objIds);
            Map<String, NewUserReportVO> map = newUserReportVOList.stream().collect(Collectors.toMap(NewUserReportVO::getId, Function.identity()));

            List<DictData> dictDataList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_VOLTAGE_STAND.getCode()).getData();
            Map<String, DictData> dictDataMap = dictDataList.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));
            map.forEach((objId, item) -> {
                PollutionSubstationDTO pollutionSubstationDTO = new PollutionSubstationDTO();
                pollutionSubstationDTO.setPowerFlag(PowerFlagEnum.NO_GRID_SIDE.getCode());
                pollutionSubstationDTO.setId(objId);
                pollutionSubstationDTO.setName(item.getProjectName());
                pollutionSubstationDTO.setLng(item.getLongitude());
                pollutionSubstationDTO.setLat(item.getLatitude());
                pollutionSubstationDTO.setVoltageLevel(dictDataMap.get(item.getVoltageLevel()).getName());
                result.add(pollutionSubstationDTO);
            });

        }
        if (CollUtil.isNotEmpty(powerLedgerList)) {
            List<Line> lineList = lineMapper.selectList(new LambdaQueryWrapper<Line>().in(Line::getId, powerLedgerList.stream().map(LineDetail::getId).distinct().collect(Collectors.toList())).eq(Line::getState, DataStateEnum.ENABLE.getCode()));
            List<String> stationIds = lineList.stream().map(it -> it.getPids().split(StrUtil.COMMA)[LineBaseEnum.SUB_LEVEL.getCode()]).collect(Collectors.toList());
            List<SubstationDTO> stationList = substationMapper.getSubstationById(stationIds);
            stationList.forEach(item -> {
                PollutionSubstationDTO pollutionSubstationDTO = new PollutionSubstationDTO();
                pollutionSubstationDTO.setPowerFlag(PowerFlagEnum.GRID_SIDE.getCode());
                pollutionSubstationDTO.setId(item.getId());
                pollutionSubstationDTO.setName(item.getName());
                pollutionSubstationDTO.setLng(item.getLng());
                pollutionSubstationDTO.setLat(item.getLat());
                pollutionSubstationDTO.setVoltageLevel(item.getScale());
                result.add(pollutionSubstationDTO);
            });
        }
        return result;
    }

    @Override
    public List<PollutionLineInfoDTO> getPollutionLineInfo(List<String> lineId) {
        List<PollutionLineInfoDTO> pollutionLineInfoDTOList;
        // 获取终端信息
        pollutionLineInfoDTOList = deviceMapper.getPollutionDeviceInfo(lineId);
        List<DictData> manufacturerList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_MANUFACTURER.getCode()).getData();
        List<DictData> devTypeList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_TYPE.getCode()).getData();
        List<DictData> businessTypeList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.BUSINESS_TYPE.getCode()).getData();
        List<DictData> loadTypeList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.INTERFERENCE_SOURCE_TYPE.getCode()).getData();
        List<DictData> voltageList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_VOLTAGE_STAND.getCode()).getData();
        for (PollutionLineInfoDTO pollutionLineInfoDTO : pollutionLineInfoDTOList) {
            // 制造厂商
            Optional<DictData> temp = manufacturerList.stream().filter(item -> item.getId().equals(pollutionLineInfoDTO.getManufacturer())).findAny();
            pollutionLineInfoDTO.setManufacturer(temp.map(DictData::getName).orElse(null));
            // 终端类型
            Optional<DictData> temp1 = devTypeList.stream().filter(item -> item.getId().equals(pollutionLineInfoDTO.getDevType())).findAny();
            pollutionLineInfoDTO.setDevType(temp1.map(DictData::getName).orElse(null));
            // 行业类型
            Optional<DictData> temp2 = businessTypeList.stream().filter(item -> item.getId().equals(pollutionLineInfoDTO.getBusinessType())).findAny();
            pollutionLineInfoDTO.setBusinessType(temp2.map(DictData::getName).orElse(null));
            // 干扰源类型
            Optional<DictData> temp3 = loadTypeList.stream().filter(item -> item.getId().equals(pollutionLineInfoDTO.getLoadType())).findAny();
            pollutionLineInfoDTO.setLoadType(temp3.map(DictData::getName).orElse(null));
            // 电压等级
            Optional<DictData> temp4 = voltageList.stream().filter(item -> item.getId().equals(pollutionLineInfoDTO.getLineVoltage())).findAny();
            pollutionLineInfoDTO.setLineVoltage(temp4.map(DictData::getName).orElse(null));

            // 变电站电压等级
            Optional<DictData> temp5 = voltageList.stream().filter(item -> item.getId().equals(pollutionLineInfoDTO.getSubVoltage())).findAny();
            pollutionLineInfoDTO.setSubVoltage(temp5.map(DictData::getName).orElse(null));


            // 电网侧
            pollutionLineInfoDTO.setPowerFlag(pollutionLineInfoDTO.getPowerFlag().equals("0") ? "电网侧" : "非电网侧");
        }
        return pollutionLineInfoDTOList;
    }

    @Override
    public void updateLineRunFlag(String devId, Integer status) {
        List<String> lineIds = new ArrayList<>();
        // 获取母线
        List<String> subLineIds = lineMapper.getSubIdByPid(devId);
        // 母线再获取所有监测点id
        for (String subLineId : subLineIds) {
            List<String> lineIdsTemp = lineMapper.getSubIdByPid(subLineId);
            lineIds.addAll(lineIdsTemp);
        }
        if(CollUtil.isNotEmpty(lineIds)){
            lineDetailMapper.updateLineRunFlagBatch(lineIds, status);
        }
    }

    @Override
    public void updatePids() {
        List<Line> list = this.list();
        List<String> strings = this.checkPidsError(list);
        if(CollUtil.isNotEmpty(strings)){
            for (String msg : strings) {
                // 1. 按 | 分割成三部分
                String[] parts = msg.split(" \\| ");
                // 2. 提取节点 ID
                String id = parts[0].replace("节点ID：", "").trim();
                // 3. 提取正确 pids（去掉括号）
                String newPids = parts[2].replace("正确pids：[", "").replace("]", "").trim();
                this.update(new LambdaUpdateWrapper<Line>()
                        .set(Line::getPids, newPids)
                        .eq(Line::getId, id));


            }
        }
    }
    /**
     * 校验所有节点 pids 是否正确
     * 正确规则：去掉开头0 + 去掉自身ID，只保留祖先链
     */
    public List<String> checkPidsError(List<Line> allList) {
        List<String> errorList = new ArrayList<>();
        Map<String, Line> idMap = allList.stream().collect(Collectors.toMap(Line::getId,Function.identity()));
        for (Line node : allList) {
            // 1. 生成正确格式的 pids（你的规则）
            String correctPids = getCorrectPids(node.getId(), idMap);
            // 2. 数据库存储的 pids
            String dbPids = node.getPids() == null ? "" : node.getPids().trim();
            // 3. 对比，不一致就是错误
            if (!correctPids.equals(dbPids)) {
                errorList.add("节点ID：" + node.getId() +
                        " | 数据库pids：[" + dbPids +
                        "] | 正确pids：[" + correctPids + "]");
            }
        }
        return errorList;
    }

    /**
     * 核心：生成【你要求】的正确 pids
     * 规则：
     * 1. 向上遍历所有祖先
     * 2. 去掉开头 0
     * 3. 去掉最后一位自身ID
     * 4. 用逗号拼接
     */
    private String getCorrectPids(String nodeId, Map<String, Line> idMap) {
        Deque<String> pathDeque = new LinkedList<>();
        String currentId = nodeId;
        // 向上收集所有节点（包含自身 + 所有祖先 + 0）
        while (currentId != null && !currentId.isEmpty()) {
            Line node = idMap.get(currentId);
            if (ObjectUtil.isNotNull(node)) {
                // 头插，保证顺序正确
                pathDeque.addFirst(currentId);
                currentId = node.getPid();
            }
        }
        // 转列表
        List<String> path = new ArrayList<>(pathDeque);

        // 1. 去掉开头的 0
        if (!path.isEmpty() && "0".equals(path.get(0))) {
            path.remove(0);
        }
        // 2. 去掉最后一位（自身ID）
        if (!path.isEmpty()) {
            path.remove(path.size() - 1);
        }
        // 拼接成最终正确 pids
        return String.join(",", path);
    }

    @Override
    public List<Overlimit> getOverLimitByList(PollutionParamDTO pollutionParamDTO) {
        return overlimitMapper.selectBatchIds(pollutionParamDTO.getLineList());
    }

    /**
     * 获取父级每层数据
     */
    private List<LineStatisticsTableVO> getTreeData(List<String> lineIndexes, DeviceInfoParam.BusinessParam steadyParam) {
        // 监测点集合
        List<LineStatisticsTableVO> monitorList = lineMapper.getLineStatisticsTableData(lineIndexes);
        // 母线集合
        List<LineStatisticsTableVO> busBarList = lineMapper.getLineInfoByTableList(monitorList.stream().map(LineStatisticsTableVO::getPid).distinct().collect(Collectors.toList()));
        // 终端集合
        List<LineStatisticsTableVO> deviceList = lineMapper.getLineInfoByTableList(busBarList.stream().map(LineStatisticsTableVO::getPid).distinct().collect(Collectors.toList()));
        // 变电站集合
        List<LineStatisticsTableVO> substationList = lineMapper.getLineInfoByTableList(deviceList.stream().map(LineStatisticsTableVO::getPid).distinct().collect(Collectors.toList()));
        // 供电公司集合
        List<LineStatisticsTableVO> powerCompanyList = lineMapper.getLineInfoByTableList(substationList.stream().map(LineStatisticsTableVO::getPid).distinct().collect(Collectors.toList()));

        setChildesList(substationList, monitorList);

        powerCompanyList.stream().peek(item -> item.setChildren(getChildCategoryList(item, substationList))).collect(Collectors.toList());

        return powerCompanyList;
    }

    private void setChildesList(List<LineStatisticsTableVO> item, List<LineStatisticsTableVO> childes) {
        Map<String, List<LineStatisticsTableVO>> groupLine;
        groupLine = childes.stream().collect(Collectors.groupingBy(steadyQualifyVO -> {
            String[] pid = steadyQualifyVO.getPidS().split(",");
            return pid[LineBaseEnum.SUB_LEVEL.getCode()];
        }));
        item.stream().peek(steadyQualifyVO -> {
            if (!CollectionUtils.isEmpty(groupLine.get(steadyQualifyVO.getId()))) {
                steadyQualifyVO.setChildren(groupLine.get(steadyQualifyVO.getId()));
            }
        }).collect(Collectors.toList());
    }

    /**
     * 组装树层级
     */
    private List<LineStatisticsTableVO> getChildCategoryList(LineStatisticsTableVO item, List<LineStatisticsTableVO> child) {
        return child.stream().filter(allItem -> allItem.getPid().equals(item.getId())).collect(Collectors.toList());
    }

    public List<PqsCommunicate> getCommunicate(String devId, DateTime startTime, DateTime endTime) {
        InfluxQueryWrapper influxQueryWrapper = new InfluxQueryWrapper(PqsCommunicate.class);
        influxQueryWrapper.eq(PqsCommunicate::getDevId, devId).between(InfluxDbSqlConstant.TIME, startTime.toString(), endTime.toString());
        return pqsCommunicateMapper.selectByQueryWrapper(influxQueryWrapper);
    }

    @Override
    public List<AreaLineInfoVO> getBaseLineAreaInfo(List<String> lineIndex, String searchValue, Integer comFlag) {
        List<AreaLineInfoVO> resList = this.baseMapper.getBaseLineAreaInfo(lineIndex, searchValue, comFlag);
        List<String> userIds = resList.stream().map(AreaLineInfoVO::getObjId).filter(StrUtil::isNotBlank).collect(Collectors.toList());
        Map<String, NewUserReportVO> userReportVOMap = new HashMap<>();
        if (CollUtil.isNotEmpty(userIds)) {
            List<NewUserReportVO> data = userLedgerService.getUserReportByIds(userIds);
            if (CollUtil.isNotEmpty(data)) {
                userReportVOMap = data.stream().collect(Collectors.toMap(NewUserReportVO::getId, Function.identity()));
            }
        }
        NewUserReportVO newUserReportVO;
        for (AreaLineInfoVO areaLineInfoVO : resList) {
            if (StrUtil.isNotBlank(areaLineInfoVO.getObjId())) {
                if (userReportVOMap.containsKey(areaLineInfoVO.getObjId())) {
                    newUserReportVO = userReportVOMap.get(areaLineInfoVO.getObjId());
                    areaLineInfoVO.setSubId(newUserReportVO.getId());
                    areaLineInfoVO.setSubName(newUserReportVO.getProjectName());
                    areaLineInfoVO.setLat(newUserReportVO.getLatitude());
                    areaLineInfoVO.setLng(newUserReportVO.getLongitude());
                    areaLineInfoVO.setObjName(newUserReportVO.getProjectName());
                }
            }
        }
        return resList;
    }

    @Override
    public List<Line> getBaseLineList(List<String> lineIndex) {
        LambdaQueryWrapper<Line> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Line::getState, DataStateEnum.ENABLE.getCode()).in(Line::getId, lineIndex);
        return this.list(lambdaQueryWrapper);
    }


    /**
     * @Description: 通过部门索引查询其下监测点数
     * @Param: [deviceInfoParam] 监测点查询条件
     * @return: java.util.List<com.njcn.device.pq.pojo.vo.DeptLineCountVO>
     * @Author: clam
     * @Date: 2022/10/10
     */
    @Override
    public List<DeptLineCountVO> getDeptLineCount(DeviceInfoParam deviceInfoParam) {
        List<DeptLineCountVO> deptLineCountVOList = new ArrayList<>();
        //获取所有监测点
        List<GeneralDeviceDTO> generalDeviceDTOList = generalDeviceService.getDeviceInfoAsDept(deviceInfoParam, null, Stream.of(1).collect(Collectors.toList()));
        for (GeneralDeviceDTO generalDeviceDTO : generalDeviceDTOList) {
            //根据部门id去获取省份信息
            DeptLineCountVO deptLineCountVO = new DeptLineCountVO();
            deptLineCountVO.setIndex(generalDeviceDTO.getIndex());
            deptLineCountVO.setName(generalDeviceDTO.getName());
            deptLineCountVO.setNumber(generalDeviceDTO.getLineIndexes().size());
            deptLineCountVOList.add(deptLineCountVO);
        }

/*        Map<String, Integer> collect = deptLineCountVOList.stream ( ).collect (Collectors.groupingBy (DeptLineCountVO::getName, Collectors.summingInt (DeptLineCountVO::getNumber)));
        List<DeptLineCountVO> result = new ArrayList<DeptLineCountVO>();

        for (Map.Entry<String, Integer> entry : collect.entrySet()) {
            DeptLineCountVO deptLineCountVO = new DeptLineCountVO();
            deptLineCountVO.setName (entry.getKey());
            deptLineCountVO.setNumber (entry.getValue());
            result.add(deptLineCountVO);
        }*/
        deptLineCountVOList = deptLineCountVOList.stream().sorted(Comparator.comparing(DeptLineCountVO::getNumber, Comparator.reverseOrder())).collect(Collectors.toList());
        return deptLineCountVOList;
    }

    /**
     * @param devDataType
     * @Description: 获取变电站和监测点的关系（分稳态暂态）
     * @Param: [devDataType]
     * @return: java.util.Map<java.lang.String, java.util.List < java.lang.String>>
     * @Author: clam
     * @Date: 2022/10/20
     */
    @Override
    public Map<String, List<String>> getLineBySubstationRelation(Integer devDataType) {

        Map<String, List<String>> map = new HashMap<>();

        List<Line> deptLines = lineMapper.getLineBySubstationRelation(devDataType);
        Map<String, List<String>> collect = deptLines.stream().collect(Collectors.groupingBy(Line::getPids, Collectors.mapping(Line::getId, Collectors.toList())));

        return collect;
    }

    @Override
    public List<LineDetailDataVO> getLineDetailList(List<String> lineIds) {
        List<DictData> data = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_VOLTAGE_STAND.getCode()).getData();
        Map<String, String> dicMap = data.stream().collect(Collectors.toMap(DictData::getId, DictData::getValue));
        List<LineDetailDataVO> lineDetailInfo = lineDetailMapper.getLineDetailInfo(lineIds);
        lineDetailInfo.forEach(item -> {
            if (dicMap.containsKey(item.getScale())) {
                item.setScale(dicMap.get(item.getScale()));
            }
        });
        return lineDetailInfo;
    }

    /**
     * @param subIndex
     * @Description: 获取变电站下终端数
     * @Param: [subIndex]
     * @return: java.lang.Integer
     * @Author: clam
     * @Date: 2022/11/9
     */
    @Override
    public Integer getDeviceCountBySubstation(String subIndex) {

        Integer count = lineDetailMapper.getDeviceCountBySubstation(subIndex);

        return count;
    }

    /**
     * @param subIndex
     * @Description: 获取变电站下监测点数
     * @Param: [subIndex]
     * @return: java.lang.Integer
     * @Author: clam
     * @Date: 2022/11/9
     */
    @Override
    public Integer getLineCountBySubstation(String subIndex) {

        Integer count = lineDetailMapper.getLineCountBySubstation(subIndex);

        return count;
    }


    /**
     * 根据用户选择的时间区间返回月份日期
     */
    @SneakyThrows
    private List<String> getIntervalTime(String startTime, String endTime) {
        List<String> times = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Date start = sdf.parse(startTime);
        Date end = sdf.parse(endTime);
        // 同月
        if (start.getTime() == end.getTime()) {
            String time = startTime.substring(0, 7);
            times.add(time);
        } else if (start.getYear() == end.getYear()) {
            // 同年
            int startM = start.getMonth() + 1;
            int endM = end.getMonth() + 1;
            int temp = endM - startM;
            for (int i = 0; i <= temp; i++) {
                String time = start.getYear() + 1900 + "";
                int month = startM + i;
                if (month < 10) {
                    time = time + "-0" + month;
                } else {
                    time = time + "-" + month;
                }
                times.add(time);
            }
        } else {
            // 不同年!!!!这里忽略了年份之间跨年的情况
            int startY = start.getYear() + 1900;
            int startM = start.getMonth() + 1;
            int endY = end.getYear() + 1900;
            int endM = end.getMonth() + 1;
            int tempS = 12 - startM;
            // 连续的年份
            if (endY - startY == 1) {
                // 第一年的时间获取
                for (int i = 0; i <= tempS; i++) {
                    int month = startM + i;
                    String time = startY + "-";
                    if (month < 10) {
                        time = time + "0" + month;
                    } else {
                        time = time + month;
                    }
                    times.add(time);
                }
                // 第二年的时间获取

                for (int i = 1; i <= endM; i++) {
                    String time = endY + "-";
                    if (i < 10) {
                        time = time + "0" + i;
                    } else {
                        time = time + i;
                    }
                    times.add(time);
                }
            } else {
                // 不连续的年份
                // 第一年的时间获取
                for (int i = 0; i <= tempS; i++) {
                    int month = startM + i;
                    String time = startY + "-";
                    if (month < 10) {
                        time = time + "0" + month;
                    } else {
                        time = time + month;
                    }
                    times.add(time);
                }
                int tempY = endY - startY;
                // 中间年份的时间
                for (int i = 1; i < tempY; i++) {
                    for (int j = 1; j <= 12; j++) {
                        String time = startY + i + "-";
                        if (j < 10) {
                            time = time + "0" + j;
                        } else {
                            time = time + j;
                        }
                        times.add(time);
                    }
                }
                // 最后一年的时间获取
                for (int i = 1; i <= endM; i++) {
                    String time = endY + "-";
                    if (i < 10) {
                        time = time + "0" + i;
                    } else {
                        time = time + i;
                    }
                    times.add(time);
                }
            }

        }
        return times;
    }
}
