package com.njcn.serviceimpl.data;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import com.njcn.pojo.commons.wave.AnalyWaveModel;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.njcn.mapper.configuration.DeviceDetailInfoMapper;
import com.njcn.mapper.configuration.DeviceDetailMapper;
import com.njcn.mapper.configuration.DeviceMapper;
import com.njcn.mapper.configuration.DicDataMapper;
import com.njcn.mapper.configuration.DicDataTypeMapper;
import com.njcn.mapper.configuration.GDInforMapper;
import com.njcn.mapper.configuration.LineDetailMapper;
import com.njcn.mapper.configuration.LineMapper;
import com.njcn.mapper.configuration.NodeInformationMapper;
import com.njcn.mapper.configuration.ProvinceMapper;
import com.njcn.mapper.configuration.SubStationMapper;
import com.njcn.mapper.configuration.SubVoltageMapper;
import com.njcn.mapper.data.EventDetailMapper;
import com.njcn.pojo.advanced.CauseStruct;
import com.njcn.pojo.advanced.EntityAdvancedData;
import com.njcn.pojo.advanced.Rect;
import com.njcn.pojo.commons.AreaGeneralData;
import com.njcn.pojo.commons.EventEigDetail;
import com.njcn.pojo.commons.EventInfoDetail;
import com.njcn.pojo.commons.RedisDB;
import com.njcn.pojo.commons.area.ReasonStatisc;
import com.njcn.pojo.commons.area.StatisticsEventDetail;
import com.njcn.pojo.commons.area.VoltageReason;
import com.njcn.pojo.commons.area.VoltageType;
import com.njcn.pojo.configuration.Device;
import com.njcn.pojo.configuration.DeviceDetailInfo;
import com.njcn.pojo.configuration.DicData;
import com.njcn.pojo.configuration.DicType;
import com.njcn.pojo.configuration.GDInformation;
import com.njcn.pojo.configuration.Line;
import com.njcn.pojo.configuration.LineDetail;
import com.njcn.pojo.configuration.NodeInformation;
import com.njcn.pojo.configuration.Province;
import com.njcn.pojo.configuration.SubStation;
import com.njcn.pojo.configuration.SubVoltage;
import com.njcn.pojo.data.EventDetail;
import com.njcn.pojo.data.EventDetailExcelBody;
import com.njcn.pojo.excelBody.DeviceDetailExcelBody;
import com.njcn.pojo.excelBody.DeviceExcelBody;
import com.njcn.pojo.excelBody.DicDataExcelBody;
import com.njcn.pojo.excelBody.DicTypeExcelBody;
import com.njcn.pojo.excelBody.GDExcelBody;
import com.njcn.pojo.excelBody.LineDetailExcelBody;
import com.njcn.pojo.excelBody.LineExcelBody;
import com.njcn.pojo.excelBody.ProvinceExcelBody;
import com.njcn.pojo.excelBody.SubStationExcelBody;
import com.njcn.pojo.excelBody.SubVoltageExcelBody;
import com.njcn.service.commons.IWaveService;
import com.njcn.service.data.EventDetailService;
import com.njcn.serviceimpl.commons.WaveServiceImpl;
import com.njcn.shiro.token.TokenManager;
import com.njcn.utils.AnalyWave;
import com.njcn.utils.AppConfig;
import com.njcn.utils.BalanceUtil;
import com.njcn.utils.JnaCallC;
import com.njcn.utils.JnaCallCause;
import com.njcn.utils.JnaCallDll;
import com.njcn.utils.PubUtils;
import com.njcn.utils.UserUtil;
import com.njcn.utils.redis.JedisManager;
import com.njcn.utils.redis.RedisCacheUtil;

import tk.mybatis.mapper.entity.Example;


@Service
public class EventDetailServiceImpl implements EventDetailService {

    private static final Logger logger = LoggerFactory.getLogger(EventDetailServiceImpl.class);

    private static final int MAXLENGTH = 128 * 3000; //波形最大值计算

    private int backNumber = -1;

    @Autowired
    private EventDetailMapper eventDetailMapper;

    @Autowired
    private UserUtil userUtil;

    @Autowired
    private RedisCacheUtil redisCacheUtil;

    @Resource
    private IWaveService iWaveService;
    @Autowired
    private AppConfig appConfig;

    @Autowired
    private JedisManager jedisManager;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private DeviceDetailMapper deviceDetailMapper;

    @Autowired
    private GDInforMapper gdInforMapper;

    @Autowired
    private LineDetailMapper lineDetailMapper;

    @Autowired
    private LineMapper lineMapper;

    @Autowired
    private ProvinceMapper provinceMapper;

    @Autowired
    private SubStationMapper subStationMapper;

    @Autowired
    private SubVoltageMapper subVoltageMapper;

    @Autowired
    private DicDataTypeMapper dicDataTypeMapper;

    @Autowired
    private DicDataMapper dicDataMapper;

    @Autowired
    private NodeInformationMapper nodeInformationMapper;

    @Autowired
    private DeviceDetailInfoMapper deviceDetailInfoMapper;


    /**
     * 收集需要导出的离线数据
     * 1：pqs_eventDetail条件范围内的数据
     * 2：获取pq_line、pq_lineDetail的数据
     * 3：获取PQ_SubVoltage的数据
     * 4：获取pq_device、pq_deviceDetail的数据
     * 5：获取pq_substation的数据
     * 6：获取pq_GDInformation数据
     * 7：获取pq_provice数据
     * 8：获取pq_dictype数据
     * 9：获取pq_dicdata数据
     *
     * @param area      区域
     * @param startTime 起始时间
     * @param endTime   截止时间
     */
    @Override
    public Boolean getEventDetailList(String area, Date startTime, Date endTime) {
        Boolean flag = false;
        List<EventDetailExcelBody> eventDetails = new ArrayList<>();
        List<DeviceDetailExcelBody> deviceDetails = deviceDetailMapper.selectAllExcelData();
        List<DeviceExcelBody> devices = deviceMapper.selectAllExcelData();
        List<GDExcelBody> gds = gdInforMapper.selectAllExcelData();
        List<LineDetailExcelBody> lineDetails = lineDetailMapper.selectAllExcelData();
        List<LineExcelBody> lines = lineMapper.selectAllExcelData();
        List<ProvinceExcelBody> provinces = provinceMapper.selectAllExcelData();
        List<SubStationExcelBody> subStations = subStationMapper.selectAllExcelData();
        List<SubVoltageExcelBody> subVoltages = subVoltageMapper.selectAllExcelData();
        List<DicTypeExcelBody> dicTypes = dicDataTypeMapper.selectAllExcelData();
        List<DicDataExcelBody> dicDatas = dicDataMapper.selectAllExcelData();

        List<Integer> linesIndex = userUtil.getAllLineIndexs(area);
        //根据索引获取字典名
        DicData dicData = new DicData();
        dicData.setDicIndex(area);
        dicData = dicDataMapper.selectOne(dicData);
        String name = "";
        if (null != dicData) {
            name = dicData.getDicName();
        }
        //分片1000个监测点
        if (linesIndex.size() > 1000) {
            //需要循环的次数
            int times = ((linesIndex.size() % 1000 == 0) ? linesIndex.size() / 1000 : (linesIndex.size() / 1000 + 1));
            for (int i = 1; i <= times; i++) {
                if (linesIndex.size() > 1000) {
                    List<Integer> temp = linesIndex.subList(0, 1000);
                    List<EventDetailExcelBody> tempList = eventDetailMapper.getEventDetailList(startTime, endTime, temp);
                    eventDetails.addAll(tempList);
                    temp.clear();
                } else {
                    List<EventDetailExcelBody> tempList = eventDetailMapper.getEventDetailList(startTime, endTime, linesIndex);
                    eventDetails.addAll(tempList);
                }
            }
        } else {
            eventDetails = eventDetailMapper.getEventDetailList(startTime, endTime, linesIndex);
        }
        OutputStream out = null;
        String filePath = appConfig.getTmppath() + "njcntemp" + File.separator + "excel9900" + File.separator + name + new SimpleDateFormat("yyyy-MM-dd").format(startTime) + "-" + new SimpleDateFormat("yyyy-MM-dd").format(endTime) + ".xlsx";
        try {
            PubUtils.createFile(filePath);
            out = new FileOutputStream(filePath);
            ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
            //写第一个sheet, sheet1  数据全是List<String> 无模型映射关系
            Sheet sheet1 = new Sheet(1, 0, EventDetailExcelBody.class);
            sheet1.setSheetName("eventDetail");
            writer.write(eventDetails, sheet1);

            Sheet sheet2 = new Sheet(2, 0, ProvinceExcelBody.class);
            sheet2.setSheetName("province");
            writer.write(provinces, sheet2);

            Sheet sheet3 = new Sheet(3, 0, GDExcelBody.class);
            sheet3.setSheetName("gdInformation");
            writer.write(gds, sheet3);

            Sheet sheet4 = new Sheet(4, 0, SubStationExcelBody.class);
            sheet4.setSheetName("substation");
            writer.write(subStations, sheet4);


            Sheet sheet5 = new Sheet(5, 0, DeviceExcelBody.class);
            sheet5.setSheetName("device");
            writer.write(devices, sheet5);


            Sheet sheet6 = new Sheet(6, 0, DeviceDetailExcelBody.class);
            sheet6.setSheetName("deviceDetail");
            writer.write(deviceDetails, sheet6);


            Sheet sheet7 = new Sheet(7, 0, SubVoltageExcelBody.class);
            sheet7.setSheetName("subvoltage");
            writer.write(subVoltages, sheet7);


            Sheet sheet8 = new Sheet(8, 0, LineDetailExcelBody.class);
            sheet8.setSheetName("lineDetail");
            writer.write(lineDetails, sheet8);


            Sheet sheet9 = new Sheet(9, 0, LineExcelBody.class);
            sheet9.setSheetName("line");
            writer.write(lines, sheet9);

            Sheet sheet10 = new Sheet(10, 0, DicTypeExcelBody.class);
            sheet10.setSheetName("dicType");
            writer.write(dicTypes, sheet10);

            Sheet sheet11 = new Sheet(11, 0, DicDataExcelBody.class);
            sheet11.setSheetName("dicData");
            writer.write(dicDatas, sheet11);
            writer.finish();
            flag = true;
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            try {
                out.close();
                flag = true;
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
        //进行存储，方便接下来的下载操作
        String key = TokenManager.getUserId() + TokenManager.getSysType();
        //清理干净，存放最新的数据
        jedisManager.deleteByKey(RedisDB.SHORT_TIME_QUERY, key);
        jedisManager.saveValueByKey(RedisDB.SHORT_TIME_QUERY, key, filePath, RedisDB.SHORT_TIME);
        return flag;
    }


    /**
     * 获取导出离线数据的波形数据
     * <p>
     * 需要按装置IP来区分下面监测点
     *
     * @param startTime 起始时间
     * @param endTime   截止时间
     * @param area      区域
     */
    @Override
    public Map<String, List<String>> getEventDetailIndexList(String area, Date startTime, Date endTime) {
        //map的key为装置IP，value为下载波形的本地路径
        Map<String, List<String>> files = new HashMap<>();
        //map的key为装置ID，value为该装置下的监测点ID
        Map<Integer, List<Integer>> data = userUtil.getDeviceAndLineIndexs(area);
        if (!CollectionUtils.isEmpty(data)) {
            Iterator<Map.Entry<Integer, List<Integer>>> it = data.entrySet().iterator();
            while (it.hasNext()) {
                List<String> filePath = new ArrayList<>();
                Map.Entry<Integer, List<Integer>> entry = it.next();
                //根据装置索引获取装置信息，主要为了IP
                Integer deviceIndex = entry.getKey();
                Device device = new Device();
                device.setDevIndex(Long.valueOf(deviceIndex));
                device = deviceMapper.selectOne(device);
                if (null == device) {
                    //装置信息为空，直接pass到下一个
                    continue;
                }
                String path = appConfig.getWavePath();
                // 从终端表获取IP
                String ip = File.separator + device.getIp();
                path = path + ip;
                //获取当前监测点下时间范围内所有暂降事件
                List<Integer> indexTemp = entry.getValue();
                List<EventDetailExcelBody> tempList = eventDetailMapper.getEventDetailList(startTime, endTime, indexTemp);
                //不为空的时候，针对每个暂降事件进行判断有没有波形文件
                if (!CollectionUtils.isEmpty(tempList)) {
                    for (EventDetailExcelBody eventDetailExcelBody : tempList) {
                        if (Integer.parseInt(eventDetailExcelBody.getFileFlag()) == 1) {
                            //说明该事件被招到本地，现在还需判断本地有没有当前文件
                            String waveName = getWaveName(eventDetailExcelBody, path);
                            //获取文件名有误，跳走，下一个
                            if (StringUtils.isBlank(waveName)) {
                                continue;
                            }
                            String pathTemp = path + File.separator + waveName;
                            File file = new File(pathTemp);
                            // 判断文件是否存在
                            if (file.isFile() && file.exists()) {
                                //CFG文件路径
                                filePath.add(pathTemp);
                                //DAT文件路径
                                filePath.add(pathTemp.replace("CFG", "DAT"));
                            }
                        }
                    }
                }
                files.put(ip, filePath);
            }
        }
        return files;
    }

    //根据暂降事件获取波形文件名
    private String getWaveName(EventDetailExcelBody eventDetail, String path) {
        String waveName = eventDetail.getWaveName();
        if (StringUtils.isNotBlank(waveName)) {
            waveName = waveName + ".CFG";
        } else {
            String timeID;
            String dateString = eventDetail.getTimeId();
            String year = dateString.substring(0, 10);
            year = year.replaceAll("-", "");
            String hour = dateString.substring(11);
            hour = hour.replaceAll(":", "");
            timeID = year + "_" + hour + "_" + eventDetail.getMs();
            int lineID = eventDetail.getLineId().intValue() % 10;
            timeID = lineID + "_" + timeID;
            waveName = timeID + ".CFG";
        }
        return waveName;
    }

    /**
     * 根据流，将文件流中的数据读出来
     */
    @Override
    public Boolean dealWithData(MultipartFile file) {
        boolean flag = false;
        List<EventDetail> eventDetails;
        List<Province> provinces;
        List<GDInformation> gdInformations;
        List<SubStation> subStations;
        List<Device> devices;
        List<DeviceDetailInfo> deviceDetails;
        List<SubVoltage> subVoltages;
        List<Line> lines;
        List<LineDetail> lineDetails;
        List<DicType> dicTypes;
        List<DicData> dicDatas;
        //从用户上传的文件中获取数据映射到实体中，等待清洗
        try {
            eventDetails = getEventDetail(file);
            lineDetails = getLineDetail(file);
            lines = getLine(file);
            subVoltages = getSubVoltages(file);
            deviceDetails = getDeviceDetail(file);
            devices = getDevice(file);
            subStations = getSubstation(file);
            gdInformations = getGdInfomation(file);
            provinces = getProvince(file);
            dicDatas = getDicData(file);
            dicTypes = getDicType(file);
        } catch (Exception e) {
            logger.error("读取数据过程有误，异常为：" + e.toString());
            throw new NumberFormatException("读取数据过程有误");
        }
        //数据获取完毕后开始清洗，插入数据的操作
        try {
            //字典类型表
            if (!CollectionUtils.isEmpty(dicTypes)) {
                for (DicType dicType : dicTypes) {
                    //首先根据名称、状态查询有没有重复的
                    DicType dicType1 = new DicType();
                    dicType1.setDicTypeName(dicType.getDicTypeName());
                    dicType1.setState(1);
                    dicType1 = dicDataTypeMapper.selectOne(dicType1);
                    if (null == dicType1) {
                        //数据库中没有该记录进行插入,还需判断待插入数据的索引是否被使用
                        dicType1 = new DicType();
                        dicType1.setDicTypeIndex(dicType.getDicTypeIndex());
                        dicType1.setState(1);
                        dicType1 = dicDataTypeMapper.selectOne(dicType1);
                        if (null != dicType1) {
                            //不为空，需要生成新的索引，然后在插入
                            dicType.setDicTypeIndex(UUID.randomUUID().toString());
                            //修改关联到其他数据表
                            modifyDictypeIndex(dicType1.getDicTypeIndex(), dicType.getDicTypeIndex(), dicDatas);
                        }
                        dicDataTypeMapper.insert(dicType);
                    } else {
                        //如果有该记录，则需要修改dicData集合中所有dicTypeIndex为当前库中的index
                        modifyDictypeIndex(dicType.getDicTypeIndex(), dicType1.getDicTypeIndex(), dicDatas);
                    }
                }
            }
            //字典数据表
            if (!CollectionUtils.isEmpty(dicDatas)) {
                for (DicData dicData : dicDatas) {
                    //首先根据名称、字典类型、状态查询有没有重复的
                    DicData dicData1 = new DicData();
                    dicData1.setDicType(dicData.getDicType());
                    dicData1.setDicName(dicData.getDicName());
                    dicData1.setState(1);
                    dicData1 = dicDataMapper.selectOne(dicData1);
                    if (null == dicData1) {
                        //数据库中没有记录,还需判断待插入数据的索引是否被使用
                        dicData1 = new DicData();
                        dicData1.setDicIndex(dicData.getDicIndex());
                        dicData1.setState(1);
                        dicData1 = dicDataMapper.selectOne(dicData1);
                        if (null != dicData1) {
                            //不为空，需要生成新的索引，然后在插入
                            dicData.setDicIndex(UUID.randomUUID().toString());
                            //修改关联到其他数据表
                            modifyDicdataIndex(dicData1.getDicIndex(), dicData.getDicIndex(), subVoltages, devices, lines, lineDetails, deviceDetails, eventDetails);
                        }
                        dicDataMapper.insert(dicData);
                    } else {
                        //存在记录，则需要修改pq_subvoltage中电压等级、pq_device中装置型号、pq_line中电压等级、pq_lineDetail中干扰源类型终和行业类型、pq_deviceDetail中设备制造商、pqs_eventDetail中暂降原因 暂降类型 第一条暂降类型
                        modifyDicdataIndex(dicData.getDicIndex(), dicData1.getDicIndex(), subVoltages, devices, lines, lineDetails, deviceDetails, eventDetails);

                    }
                }
            }
            //省会表
            if (!CollectionUtils.isEmpty(provinces)) {
                for (Province province : provinces) {
                    Province province1 = new Province();
                    province1.setName(province.getName());
                    province1 = provinceMapper.selectOne(province1);
                    if (null == province1) {
                        //数据库中没有记录,还需判断待插入数据的索引是否被使用
                        province1 = new Province();
                        province1.setProvinceIndex(province.getProvinceIndex());
                        province1 = provinceMapper.selectOne(province1);
                        if (null != province1) {
                            //不为空，需要生成新索引，然后插入
                            Long currentMaxId = provinceMapper.selectMaxIndex();
                            province.setProvinceIndex(currentMaxId + 1);
                            //因新索引修改关联到的其他表
                            modifyProvinceIndex(province1.getProvinceIndex(), province.getProvinceIndex(), gdInformations);
                        }
                        provinceMapper.insert(province);
                    } else {
                        //存在记录，需要修改pq_gdinformation中的省级序号
                        modifyProvinceIndex(province.getProvinceIndex(), province1.getProvinceIndex(), gdInformations);

                    }
                }
            }
            //供电公司表
            if (!CollectionUtils.isEmpty(gdInformations)) {
                for (GDInformation gdInformation : gdInformations) {
                    GDInformation gdInformation1 = new GDInformation();
                    gdInformation1.setName(gdInformation.getName());
                    gdInformation1 = gdInforMapper.selectOne(gdInformation1);
                    if (null == gdInformation1) {
                        //数据库中没有记录,还需判断待插入数据的索引是否被使用
                        gdInformation1 = new GDInformation();
                        gdInformation1.setGdIndex(gdInformation.getGdIndex());
                        gdInformation1 = gdInforMapper.selectOne(gdInformation1);
                        if (null != gdInformation1) {
                            //不为空，需要生成新索引，然后插入
                            Long currentMaxId = gdInforMapper.selectMaxIndex();
                            gdInformation.setGdIndex(currentMaxId + 1);
                            //因新索引修改关联到的其他表
                            modifyGDIndex(gdInformation1.getGdIndex(), gdInformation.getGdIndex(), subStations, devices, subVoltages, lines, lineDetails);
                        }
                        gdInforMapper.insert(gdInformation);
                    } else {
                        //存在记录，需要修改pq_substation中的供电序号、pq_device中的供电序号、pq_subVoltage中的供电序号、pq_line中的供电序号、pq_lineDetail中的供电序号
                        modifyGDIndex(gdInformation.getGdIndex(), gdInformation1.getGdIndex(), subStations, devices, subVoltages, lines, lineDetails);
                    }
                }
            }
            //变电站
            if (!CollectionUtils.isEmpty(subStations)) {
                for (SubStation subStation : subStations) {
                    SubStation subStation1 = new SubStation();
                    subStation1.setName(subStation.getName());
                    subStation1 = subStationMapper.selectOne(subStation1);
                    if (null == subStation1) {
                        //不存在记录，还需判断待插入数据的索引是否被使用
                        subStation1 = new SubStation();
                        subStation1.setSubIndex(subStation.getSubIndex());
                        subStation1 = subStationMapper.selectOne(subStation1);
                        if (null != subStation1) {
                            //不为空，需要生成新索引，然后插入
                            Long currentMaxId = subStationMapper.selectMaxIndex();
                            subStation.setSubIndex(currentMaxId + 1);
                            //因新索引修改关联到的其他表
                            modifySubstationIndex(subStation1.getSubIndex(), subStation.getSubIndex(), devices, subVoltages, lines, lineDetails);
                        }
                        subStationMapper.insert(subStation);
                    } else {
                        //存在记录，需要修改pq_device的变电站序号、pq_subVoltage中的变电站序号、pq_line中的变电站序号、pq_lineDetail中的变电站序号
                        modifySubstationIndex(subStation.getSubIndex(), subStation1.getSubIndex(), devices, subVoltages, lines, lineDetails);
                    }
                }
            }
            //装置
            if (!CollectionUtils.isEmpty(devices)) {
                for (Device device : devices) {
                    Device device1 = new Device();
                    device1.setName(device.getName());
                    device1.setIp(device.getIp());
                    device1 = deviceMapper.selectOne(device1);
                    if (null == device1) {
                        //不存在记录，还需判断待插入数据的索引是否被使用
                        device1 = new Device();
                        device1.setDevIndex(device.getDevIndex());
                        device1 = deviceMapper.selectOne(device1);
                        if (null != device1) {
                            //不为空，需要生成新索引，然后插入
                            Long currentMaxId = deviceMapper.selectMaxIndex();
                            device.setDevIndex(currentMaxId + 1);
                            //因新索引修改关联到的其他表
                            modiyDeviceIndex(device1.getDevIndex(), device.getDevIndex(), subVoltages, deviceDetails, lines);
                        }
                        //插入前，获取本地的一个前置机索引
                        NodeInformation nodeInformation = new NodeInformation();
                        nodeInformation.setNodeStatus(1L);
                        List<NodeInformation> nodeInformations = nodeInformationMapper.select(nodeInformation);
                        if (CollectionUtils.isEmpty(nodeInformations)) {
                            device.setNodeIndex(1L);
                        } else {
                            device.setNodeIndex(nodeInformations.get(0).getNodeIndex());
                        }
                        device.setDevmodel(2L);
                        deviceMapper.insert(device);
                    } else {
                        //存在记录，需要修改pq_subVoltage中装置序号、pq_deviceDetail中装置序号、pq_line中装置序号
                        modiyDeviceIndex(device1.getDevIndex(), device.getDevIndex(), subVoltages, deviceDetails, lines);
                    }
                }
            }
            //剩下 deviceDetail subvlotage line lineDetail4张表，只需判断当前索引有没有记录，没有直接插入
            //装置详细表
            if (!CollectionUtils.isEmpty(deviceDetails)) {
                for (DeviceDetailInfo deviceDetail : deviceDetails) {
                    DeviceDetailInfo deviceDetail1 = new DeviceDetailInfo();
                    deviceDetail1.setDevIndex(deviceDetail.getDevIndex());
                    deviceDetail1 = deviceDetailInfoMapper.selectOne(deviceDetail1);
                    if (null == deviceDetail1) {
                        //因为deviceDetail表的记录是依附device表的，所以如果存在记录，则忽略，否则插入新数据
                        deviceDetailInfoMapper.insert(deviceDetail);
                    }
                }
            }
            //母线
            if (!CollectionUtils.isEmpty(subVoltages)) {
                for (SubVoltage subVoltage : subVoltages) {
                    SubVoltage subVoltage1 = new SubVoltage();
                    subVoltage1.setSubIndex(subVoltage.getSubIndex());
                    subVoltage1.setDevIndex(subVoltage.getDevIndex());
                    subVoltage1 = subVoltageMapper.selectOne(subVoltage1);
                    if (null == subVoltage1) {
                        //没有记录，说明需要插入，插入前还需判断索引是否重复
                        subVoltage1 = new SubVoltage();
                        subVoltage1.setSubvIndex(subVoltage.getSubvIndex());
                        subVoltage1 = subVoltageMapper.selectOne(subVoltage1);
                        if (null != subVoltage1) {
                            //存在记录，则需要生成新索引，然后插入
                            Long currentMaxId = subVoltageMapper.selectMaxSubvIndex();
                            subVoltage.setSubvIndex(currentMaxId + 1);
                            //因新索引修改关联到的其他表
                            modifySubVoltageIndex(subVoltage1.getSubvIndex(), subVoltage.getSubvIndex(), lines);
                        }
                        subVoltageMapper.insert(subVoltage);
                    }
                }
            }
            //监测点
            if (!CollectionUtils.isEmpty(lines)) {
                for (Line line : lines) {
                    Line line1 = new Line();
                    line1.setDevIndex(line.getDevIndex());
                    line1.setSubIndex(line.getSubIndex());
                    line1.setSubvIndex(line.getSubvIndex());
                    line1 = lineMapper.selectOne(line1);
                    if (null == line1) {
                        //没有记录，说明需要插入，插入前还需要判断索引是否重复
                        line1 = new Line();
                        line1.setLineIndex(line.getLineIndex());
                        line1 = lineMapper.selectOne(line1);
                        if (null != line1) {
                            //存在记录，则需要生成新索引，然后插入
                            Long currentId = line.getLineIndex() % 10;
                            line.setLineIndex(line.getDevIndex() * 10 + currentId);
                            //因新索引修改关联到的其他表
                            modifyLineIndex(line1.getLineIndex(), line.getLineIndex(), lineDetails, eventDetails);
                        }
                        lineMapper.insert(line);
                    }
                }
            }
            //监测点详细表
            if (!CollectionUtils.isEmpty(lineDetails)) {
                for (LineDetail lineDetail : lineDetails) {
                    LineDetail lineDetail1 = new LineDetail();
                    lineDetail1.setLineIndex(lineDetail.getLineIndex());
                    lineDetail1 = lineDetailMapper.selectOne(lineDetail1);
                    if (null == lineDetail1) {
                        //因为lineDetail表的记录是依附line表的，所以如果存在记录，则忽略，否则插入新数据
                        lineDetailMapper.insert(lineDetail);
                    }
                }
            }
            //暂降日志表
            if (CollectionUtils.isEmpty(eventDetails)) {
                for (EventDetail eventDetail : eventDetails) {
                    EventDetail eventDetail1 = new EventDetail();
                    eventDetail1.setLineId(eventDetail.getLineId());
                    eventDetail1.setTimeId(eventDetail.getTimeId());
                    eventDetail1.setMs(eventDetail.getMs());
                    eventDetail1 = eventDetailMapper.selectOne(eventDetail1);
                    if (null == eventDetail1) {
                        //不存在记录，表示需要插入，但是还需判断索引是否被使用
                        eventDetail1 = new EventDetail();
                        eventDetail1.setEventDetailIndex(eventDetail.getEventDetailIndex());
                        eventDetail1 = eventDetailMapper.selectOne(eventDetail1);
                        if (null != eventDetail1) {
                            //存在记录需要生成新索引插入
                            eventDetail.setEventDetailIndex(UUID.randomUUID().toString());
                        }
                        //插入前，将归一化处理的一些字段置为空
                        eventDetail.setEventassIndex("");
                        eventDetail.setDealTime(null);
                        eventDetailMapper.insert(eventDetail);
                    }
                }
            }
            flag = true;
        } catch (Exception e) {
            logger.error("清洗数据过程有误，异常为：" + e.toString());
            throw new NumberFormatException("清洗数据过程有误");
        }
        return flag;
    }

    /**
     * 根据流，将文件流中的数据读出来并绑定lineIndex存入eventdetail表中
     */
    @Override
    public Boolean dealWithWaveData(MultipartFile file, String lineIndex) {
        return null;
    }

    /**
     * 根据波形路径，配合索引，将事件波形日志文件入库
     *
     * @param lineIndex 监测点索引
     * @param paths     波形路径
     */
    @Override
    public void saveEventDetail(String lineIndex, List<String> paths) {
        if (CollectionUtils.isEmpty(paths)) {
            return;
        }
        //入库前需要判断该事件是否已经入库 唯一：监测点+时间+秒
        for (int i = 0; i < paths.size(); i++) {
            String path = paths.get(i);
            //获取波形数据，存在波形数据为空的可能性
            AnalyWave analyWave = new AnalyWave();
            List<List<Float>> realWave = analyWave.readComtrade(path, null, 1).getListWaveData();//获取原始波形值,抽取波形数据 iFlag传0
            List<List<Float>> result = analyWave.getEigenvalue(realWave, true);//ABC三相的持续时间和幅值
            //数据为空，跳出循环
            if (CollectionUtils.isEmpty(realWave) || CollectionUtils.isEmpty(result)) {
                continue;
            }
            //获取第一次时间
            Date firstTime = analyWave.getFirstTime();
            Integer firstMs = analyWave.getFirstMs();
            //获取CFG中读取的波形起始时间
            Date beginTime = analyWave.getTimeWave();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
            SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String strTime = sdf.format(beginTime);
            Date timeId;
            try {
                timeId = sdfTime.parse(strTime.substring(0, strTime.lastIndexOf(".")));
            } catch (Exception e) {
                throw new NumberFormatException("波形名转日期出错");
            }
            Long ms = Long.parseLong(strTime.substring(strTime.lastIndexOf(".") + 1));
            //根据lineID/timeID/MS唯一排重
            EventDetail eventDetail = new EventDetail();
            eventDetail.setTimeId(timeId);
            eventDetail.setLineId(Long.parseLong(lineIndex));
            eventDetail.setMs(ms);
            //获取波形文件名
            String waveName = path.substring(path.lastIndexOf("\\") + 1, path.lastIndexOf("."));
            eventDetail = eventDetailMapper.selectOne(eventDetail);
            if (null == eventDetail) {
                //为空，说明库中没有，需要插入新数据
                eventDetail = new EventDetail();
                String uuid = UUID.randomUUID().toString();
                eventDetail.setEventDetailIndex(uuid);
                eventDetail.setTimeId(timeId);
                eventDetail.setLineId(Long.parseLong(lineIndex));
                eventDetail.setMs(ms);
                eventDetail.setDescribe(" ");
                eventDetail.setNum(0);
                List<Float> values = getTimeAndValue(result);
                Float ptime = PubUtils.floatRound(0, values.get(1));
                eventDetail.setPersistTime(ptime);
                Float eventValue = PubUtils.floatRound(4, values.get(0));
                eventDetail.setEventValue(eventValue);
                eventDetail.setWaveType(getWaveType(values.get(0)));
                eventDetail.setEventassIndex(null);
                eventDetail.setFileFlag("1");
                eventDetail.setWaveName(waveName);
                eventDetail.setSeverity(Float.parseFloat(WaveServiceImpl.getYzd(eventDetail.getPersistTime(), eventDetail.getEventValue())));
                //获取DQ持续时间、暂降类型、暂降原因
                eventDetail.setFirstTime(firstTime);
                eventDetail.setFirstMs(firstMs);
                try {
                    getDataFromDll(eventDetail, realWave, analyWave);
                } catch (Exception e) {
                    String reason = dicDataMapper.getDicDataIndex("暂降原因", 0);
                    eventDetail.setEventReason(reason);
                    String firstType = dicDataMapper.getDicDataIndex("暂降类型", 10);
                    eventDetail.setFirstType(firstType);
                    eventDetail.setDealFlag(Integer.toString(1));
                    eventDetail.setNum(0);
                    eventDetail.setDqTime(ptime);
                }

                //根据持续时间ptime、暂降赋值eventValue计算暂降能量
                eventDetail.setEnergy(PubUtils.floatRound(3, BalanceUtil.calculateNl(ptime / 1000, eventValue)));
                //搜集完所有信息后进行入库处理
                eventDetailMapper.insert(eventDetail);
            }
        }
    }

    private void getDataFromDll(EventDetail eventDetail, List<List<Float>> lists, AnalyWave analyWave) throws Exception {
        eventDetail.setDealFlag(Integer.toString(1));
        //填充数据区域
        Rect rect = new Rect();
        CauseStruct causeStruct = new CauseStruct();

        for (int i = 0; i < lists.size(); i++) {
            rect.smp_va[i] = lists.get(i).get(1).floatValue();
            causeStruct.smp_va[i] = lists.get(i).get(1).floatValue();

            rect.smp_vb[i] = lists.get(i).get(2).floatValue();
            causeStruct.smp_vb[i] = lists.get(i).get(2).floatValue();

            rect.smp_vc[i] = lists.get(i).get(3).floatValue();
            causeStruct.smp_vc[i] = lists.get(i).get(3).floatValue();
        }

        rect.smp_len = lists.size();

        if (rect.smp_len >= MAXLENGTH) { //超过60s的波形直接抛异常给上面处理
            throw new Exception();
        }

        rect.smp_rate = (int) analyWave.getnOneWaveNum();
        causeStruct.smp_len = lists.size();
        causeStruct.smp_rate = (int) analyWave.getnOneWaveNum();

        //调用dll计算结果
        String os = System.getProperty("os.name");  // 获取当前操作系统的类型
        int beginIndex = os != null && os.startsWith("Windows") ? 1 : 0;// windows操作系统为1 否则为0
        JnaCallDll jnaCallDll;
        if(beginIndex == 1){
            jnaCallDll = new JnaCallC("qvvr_dll.dll");
        }else{
            jnaCallDll = new JnaCallC("libqvvr_dll.so");
        }
        jnaCallDll.setPath();
        jnaCallDll.setPath();

        JnaCallC.Clibrary INSTANTCE = JnaCallC.Clibrary.INSTANTCE;
        INSTANTCE.qvvr_fun(rect); // 计算暂降类型

        JnaCallDll jnaCallDll1;
        if(beginIndex == 1){
            jnaCallDll1 = new JnaCallCause("qvvr_dll_cause.dll");
        }else{
            jnaCallDll1 = new JnaCallCause("libqvvr_cause_dll.so");
        }
        jnaCallDll1.setPath();

        JnaCallCause.Causelibrary CAUSE = JnaCallCause.Causelibrary.INSTANTCE;
        CAUSE.qvvr_fun_cause(causeStruct);// 计算暂降原因

        if (causeStruct.no_cal == 1) {// 暂降原因的结果更新到数据库
            causeStruct.cause = 0;
        }

        //eventDetail.setEventReason(causeStruct.cause);根据causeStruct.cause对应pqs_dicdata的triphase查guid填入
        String reason = dicDataMapper.getDicDataIndex("暂降原因", causeStruct.cause);
        if (StringUtils.isBlank(reason)) {
            reason = "";
        }
        eventDetail.setEventReason(reason);

        if (rect.evt_num > 0) {
            eventDetail.setNum(rect.evt_num);
            eventDetail.setDqTime(PubUtils.floatRound(3, rect.evt_buf[0].hold_time_dq));
            String firstType = dicDataMapper.getDicDataIndex("暂降类型", rect.evt_buf[0].qvvr_cata_type[0]);
            if (StringUtils.isBlank(firstType)) {
                firstType = "";
            }
            eventDetail.setFirstType(firstType);

            // 排序并获取多段中最小的数据
            float[] f = new float[rect.evt_num];

            for (int i = 0; i < rect.evt_num; i++) {
                Arrays.parallelSort(rect.evt_buf[i].u3_min, 0, rect.evt_buf[i].u_min_num - 1);
                f[i] = rect.evt_buf[i].u3_min[0];
            }

            float min = f[0];
            int index = 0;

            for (int len = 1; len < f.length; len++) {
                if (min - f[len] > 0) {
                    index = len;
                    min = f[len];
                }
            }

            String type = dicDataMapper.getDicDataIndex("暂降类型", rect.evt_buf[index].qvvr_cata_type[0]);
            if (StringUtils.isBlank(type)) {
                type = "676683a0-7f80-43e6-8df8-bea8ed235d67";
            }
            eventDetail.setEventType(type);
        }
    }

    /**
     * 根据特征幅值获取事件类型
     *
     * @param aFloat 特征幅值
     */
    private int getWaveType(Float aFloat) {
        if (aFloat <= 0.05) {
            return 3;
        } else if (aFloat <= 0.9) {
            return 1;
        } else {
            return 2;
        }
    }

    /*********************************
     * 0是特征幅值（残余电压百分比）
     * 1是特征幅值（残余电压）
     * 2额定定压（动态电压）
     * 3是持续时间
     **********************************/
    //根据波形结果，获取出持续时间毫秒、特征幅值
    private List<Float> getTimeAndValue(List<List<Float>> result) {
        List<Float> timeAndValue = new ArrayList<>();
        if (!CollectionUtils.isEmpty(result)) {
            float value0 = result.get(0).get(0);
            float value1 = result.get(1).get(0);
            float value2 = result.get(2).get(0);
            float temp = value0 < value1 ? value0 : value1;
            temp = temp < value2 ? temp : value2;
            if (temp > 1) {
                //最小值大于1，说明是暂升
                temp = value0 > value1 ? value0 : value1;
                temp = temp > value2 ? temp : value2;
                timeAndValue.add(temp);
                timeAndValue.add(getTime(result, temp));
            } else {
                timeAndValue.add(temp);
                timeAndValue.add(getTime(result, temp));
            }
            return timeAndValue;
        } else {
            return timeAndValue;
        }
    }

    /*********************************
     * 0是特征幅值（残余电压百分比）
     * 1是特征幅值（残余电压）
     * 2额定定压（动态电压）
     * 3是持续时间
     **********************************/
    /**
     * 根据特征幅值获取其持续时间
     *
     * @param result 波形数据
     * @param temp   特征幅值
     */
    private Float getTime(List<List<Float>> result, float temp) {
        float value0 = result.get(0).get(0);
        float value1 = result.get(1).get(0);
        if (temp == value0) {
            return result.get(0).get(3);
        } else if (temp == value1) {
            return result.get(1).get(3);
        } else {
            return result.get(2).get(3);
        }
    }


    /**
     * 监测点表索引更改，引起关联表的索引改动
     */
    private void modifyLineIndex(Long oldIndex, Long newIndex, List<LineDetail> lineDetails, List<EventDetail> eventDetails) {
        if (!CollectionUtils.isEmpty(lineDetails)) {
            for (LineDetail lineDetail : lineDetails) {
                if (lineDetail.getLineIndex() != null & lineDetail.getLineIndex().equals(oldIndex)) {
                    lineDetail.setLineIndex(newIndex);
                }
            }
        }
        if (!CollectionUtils.isEmpty(eventDetails)) {
            for (EventDetail eventDetail : eventDetails) {
                if (eventDetail.getLineId() != null & eventDetail.getLineId().equals(oldIndex)) {
                    eventDetail.setLineId(newIndex);
                }
            }
        }
    }


    /**
     * 母线表索引更改，引起关联表的索引改动
     */
    private void modifySubVoltageIndex(Long oldIndex, Long newIndex, List<Line> lines) {
        if (!CollectionUtils.isEmpty(lines)) {
            for (Line line : lines) {
                if (line.getSubvIndex() != null & line.getSubvIndex().equals(oldIndex)) {
                    line.setSubvIndex(newIndex);
                }
            }
        }
    }

    /**
     * 装置表索引更改，引起关联表的索引改动
     */
    private void modiyDeviceIndex(Long oldIndex, Long newIndex, List<SubVoltage> subVoltages, List<DeviceDetailInfo> deviceDetails, List<Line> lines) {
        if (!CollectionUtils.isEmpty(subVoltages)) {
            for (SubVoltage subVoltage : subVoltages) {
                if (subVoltage.getDevIndex() != null & subVoltage.getDevIndex().equals(oldIndex)) {
                    subVoltage.setDevIndex(newIndex);
                }
            }
        }
        if (!CollectionUtils.isEmpty(deviceDetails)) {
            for (DeviceDetailInfo deviceDetail : deviceDetails) {
                if (deviceDetail.getDevIndex() != null & deviceDetail.getDevIndex().equals(oldIndex)) {
                    deviceDetail.setDevIndex(newIndex);
                }
            }
        }
        if (!CollectionUtils.isEmpty(lines)) {
            for (Line line : lines) {
                if (line.getDevIndex() != null & line.getDevIndex().equals(oldIndex)) {
                    line.setDevIndex(newIndex);
                }
            }
        }
    }

    /**
     * 变电站表索引更改，引起关联表的索引改动
     */
    private void modifySubstationIndex(Long oldIndex, Long newIndex, List<Device> devices, List<SubVoltage> subVoltages, List<Line> lines, List<LineDetail> lineDetails) {
        if (!CollectionUtils.isEmpty(devices)) {
            for (Device device : devices) {
                if (device.getSubIndex() != null & device.getSubIndex().equals(oldIndex)) {
                    device.setSubIndex(newIndex);
                }
            }
        }
        if (!CollectionUtils.isEmpty(subVoltages)) {
            for (SubVoltage subVoltage : subVoltages) {
                if (subVoltage.getSubvIndex() != null & subVoltage.getSubvIndex().equals(oldIndex)) {
                    subVoltage.setSubIndex(newIndex);
                }
            }
        }
        if (!CollectionUtils.isEmpty(lines)) {
            for (Line line : lines) {
                if (line.getSubIndex() != null & line.getSubIndex().equals(oldIndex)) {
                    line.setSubIndex(newIndex);
                }
            }
        }
        if (!CollectionUtils.isEmpty(lineDetails)) {
            for (LineDetail lineDetail : lineDetails) {
                if (lineDetail.getSubIndex() != null & lineDetail.getSubIndex().equals(oldIndex)) {
                    lineDetail.setSubIndex(newIndex);
                }
            }
        }
    }

    /**
     * 供电公司表索引更改，引起关联表的索引改动
     */
    private void modifyGDIndex(Long oldIndex, Long newIndex, List<SubStation> subStations, List<Device> devices, List<SubVoltage> subVoltages, List<Line> lines, List<LineDetail> lineDetails) {
        if (!CollectionUtils.isEmpty(subStations)) {
            for (SubStation subStation : subStations) {
                if (subStation.getGdIndex() != null & subStation.getGdIndex().equals(oldIndex)) {
                    subStation.setGdIndex(newIndex);
                }
            }
        }
        if (!CollectionUtils.isEmpty(devices)) {
            for (Device device : devices) {
                if (device.getGdIndex() != null & device.getGdIndex().equals(oldIndex)) {
                    device.setGdIndex(newIndex);
                }
            }
        }
        if (!CollectionUtils.isEmpty(subVoltages)) {
            for (SubVoltage subVoltage : subVoltages) {
                if (subVoltage.getGdIndex() != null & subVoltage.getGdIndex().equals(oldIndex)) {
                    subVoltage.setGdIndex(newIndex);
                }
            }
        }
        if (!CollectionUtils.isEmpty(lines)) {
            for (Line line : lines) {
                if (line.getGdIndex() != null & line.getGdIndex().equals(oldIndex)) {
                    line.setGdIndex(newIndex);
                }
            }
        }
        if (!CollectionUtils.isEmpty(lineDetails)) {
            for (LineDetail lineDetail : lineDetails) {
                if (lineDetail.getGdIndex() != null & lineDetail.getGdIndex().equals(oldIndex)) {
                    lineDetail.setGdIndex(newIndex);
                }
            }
        }
    }

    /**
     * 省级表索引更改，引起关联表的索引改动
     */
    private void modifyProvinceIndex(Long oldIndex, Long newIndex, List<GDInformation> gdInformations) {
        if (!CollectionUtils.isEmpty(gdInformations)) {
            for (GDInformation gdInformation : gdInformations) {
                if (gdInformation.getProvinceIndex() != null & gdInformation.getProvinceIndex().equals(oldIndex)) {
                    gdInformation.setProvinceIndex(newIndex);
                }
            }
        }
    }

    /**
     * 字典数据表索引更改，引起关联表的索引改动
     */
    private void modifyDicdataIndex(String oldIndex, String newIndex, List<SubVoltage> subVoltages, List<Device> devices, List<Line> lines, List<LineDetail> lineDetails, List<DeviceDetailInfo> deviceDetails, List<EventDetail> eventDetails) {
        if (!CollectionUtils.isEmpty(subVoltages)) {
            for (SubVoltage subVoltage : subVoltages) {
                if (!PubUtils.isBlank(subVoltage.getScale()) & subVoltage.getScale().equalsIgnoreCase(oldIndex)) {
                    subVoltage.setScale(newIndex);
                }
            }
        }
        if (!CollectionUtils.isEmpty(devices)) {
            for (Device device : devices) {
                if (!PubUtils.isBlank(device.getDevType()) & device.getDevType().equalsIgnoreCase(oldIndex)) {
                    device.setDevType(newIndex);
                }
            }
        }
        if (!CollectionUtils.isEmpty(lines)) {
            for (Line line : lines) {
                if (!PubUtils.isBlank(line.getScale()) & line.getScale().equalsIgnoreCase(oldIndex)) {
                    line.setScale(newIndex);
                }
            }
        }
        if (!CollectionUtils.isEmpty(lineDetails)) {
            for (LineDetail lineDetail : lineDetails) {
                if (!PubUtils.isBlank(lineDetail.getLoadType()) & lineDetail.getLoadType().equalsIgnoreCase(oldIndex)) {
                    lineDetail.setLoadType(newIndex);
                }
                if (!PubUtils.isBlank(lineDetail.getBusinessType()) & lineDetail.getBusinessType().equalsIgnoreCase(oldIndex)) {
                    lineDetail.setBusinessType(newIndex);
                }
            }
        }
        if (!CollectionUtils.isEmpty(deviceDetails)) {
            for (DeviceDetailInfo deviceDetail : deviceDetails) {
                if (!PubUtils.isBlank(deviceDetail.getManufacturer()) & deviceDetail.getManufacturer().equalsIgnoreCase(oldIndex)) {
                    deviceDetail.setManufacturer(newIndex);
                }
            }
        }
        if (!CollectionUtils.isEmpty(eventDetails)) {
            for (EventDetail eventDetail : eventDetails) {
                if (!PubUtils.isBlank(eventDetail.getEventReason()) & eventDetail.getEventReason().equalsIgnoreCase(oldIndex)) {
                    eventDetail.setEventReason(newIndex);
                }
                if (!PubUtils.isBlank(eventDetail.getEventType()) & eventDetail.getEventType().equalsIgnoreCase(oldIndex)) {
                    eventDetail.setEventType(newIndex);
                }
                if (!PubUtils.isBlank(eventDetail.getFirstType()) & eventDetail.getFirstType().equalsIgnoreCase(oldIndex)) {
                    eventDetail.setFirstType(newIndex);
                }
            }
        }
    }

    /**
     * 字典类型表索引更改，引起关联表的索引变化
     */
    private void modifyDictypeIndex(String oldIndex, String newIndex, List<DicData> dicDatas) {
        if (!CollectionUtils.isEmpty(dicDatas)) {
            for (DicData dicData : dicDatas) {
                if (!PubUtils.isBlank(dicData.getDicType()) & dicData.getDicType().equalsIgnoreCase(oldIndex)) {
                    dicData.setDicType(newIndex);
                }
            }
        }
    }


    /**
     * 根据流获取出DicType的数据
     */
    private List<DicType> getDicType(MultipartFile file) throws Exception {
        List<DicType> dicTypes = new ArrayList<>();
        List<DicTypeExcelBody> dicTypeExcelBodies = new ArrayList<>();
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
            ExcelReader reader = new ExcelReader(inputStream, ExcelTypeEnum.XLSX, null,
                    new AnalysisEventListener() {
                        @Override
                        public void invoke(Object object, AnalysisContext context) {
                            DicTypeExcelBody obj = (DicTypeExcelBody) object;
                            dicTypeExcelBodies.add(obj);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext context) {
                        }
                    }, true);
            reader.read(new Sheet(10, 1, DicTypeExcelBody.class));
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
        if (CollectionUtils.isEmpty(dicTypeExcelBodies)) {
            return dicTypes;
        } else {
            for (DicTypeExcelBody dicTypeExcelBody : dicTypeExcelBodies) {
                DicType dicType = new DicType();
                dicType.setDicTypeIndex(PubUtils.isBlank(dicTypeExcelBody.getDicTypeIndex()) ? "" : dicTypeExcelBody.getDicTypeIndex());
                dicType.setDicTypeName(PubUtils.isBlank(dicTypeExcelBody.getDicTypeName()) ? "" : dicTypeExcelBody.getDicTypeName());
                dicType.setDicTypeNumber(dicTypeExcelBody.getDicTypeNumber() == null ? null : dicTypeExcelBody.getDicTypeNumber().intValue());
                dicType.setDicTypeDiscribe(PubUtils.isBlank(dicTypeExcelBody.getDicTypeDiscribe()) ? "" : dicTypeExcelBody.getDicTypeDiscribe());
                dicType.setState(dicTypeExcelBody.getState() == null ? null : dicTypeExcelBody.getState().intValue());
                dicType.setUserIndex(PubUtils.isBlank(dicTypeExcelBody.getUserIndex()) ? "" : dicTypeExcelBody.getUserIndex());
                dicType.setUpdateTime(PubUtils.isBlank(dicTypeExcelBody.getUpdateTime()) ? null : PubUtils.string2Date(dicTypeExcelBody.getUpdateTime(), "yyyy-MM-dd HH:mm:ss"));
                dicTypes.add(dicType);
            }
        }
        return dicTypes;
    }

    /**
     * 根据流获取出DicData的数据
     */
    private List<DicData> getDicData(MultipartFile file) throws Exception {
        List<DicData> dicDatas = new ArrayList<>();
        List<DicDataExcelBody> dicDataExcelBodies = new ArrayList<>();
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
            ExcelReader reader = new ExcelReader(inputStream, ExcelTypeEnum.XLSX, null,
                    new AnalysisEventListener() {
                        @Override
                        public void invoke(Object object, AnalysisContext context) {
                            DicDataExcelBody obj = (DicDataExcelBody) object;
                            dicDataExcelBodies.add(obj);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext context) {
                        }
                    }, true);
            reader.read(new Sheet(11, 1, DicDataExcelBody.class));
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
        if (CollectionUtils.isEmpty(dicDataExcelBodies)) {
            return dicDatas;
        } else {
            for (DicDataExcelBody dicDataExcelBody : dicDataExcelBodies) {
                DicData dicData = new DicData();
                dicData.setDicIndex(PubUtils.isBlank(dicDataExcelBody.getDicIndex()) ? "" : dicDataExcelBody.getDicIndex());
                dicData.setDicName(PubUtils.isBlank(dicDataExcelBody.getDicName()) ? "" : dicDataExcelBody.getDicName());
                dicData.setDicType(PubUtils.isBlank(dicDataExcelBody.getDicType()) ? "" : dicDataExcelBody.getDicType());
                dicData.setDicNumber(dicDataExcelBody.getDicNumber() == null ? null : dicDataExcelBody.getDicNumber().intValue());
                dicData.setUpdateTime(PubUtils.isBlank(dicDataExcelBody.getUpdateTime()) ? null : PubUtils.string2Date(dicDataExcelBody.getUpdateTime(), "yyyy-MM-dd HH:mm:ss"));
                dicData.setDicLeave(dicDataExcelBody.getLeave() == null ? null : dicDataExcelBody.getLeave().intValue());
                dicData.setUserIndex(PubUtils.isBlank(dicDataExcelBody.getUserIndex()) ? "" : dicDataExcelBody.getUserIndex());
                dicData.setState(dicDataExcelBody.getState() == null ? null : dicDataExcelBody.getState().intValue());
                dicData.setTriphase(dicDataExcelBody.getTriphase() == null ? null : dicDataExcelBody.getTriphase().intValue());
                dicDatas.add(dicData);
            }
        }
        return dicDatas;
    }

    /**
     * 根据流获取出Province的数据
     */
    private List<Province> getProvince(MultipartFile file) {
        List<Province> provinces = new ArrayList<>();
        List<ProvinceExcelBody> provinceExcelBodies = new ArrayList<>();
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
            ExcelReader reader = new ExcelReader(inputStream, ExcelTypeEnum.XLSX, null,
                    new AnalysisEventListener() {
                        @Override
                        public void invoke(Object object, AnalysisContext context) {
                            ProvinceExcelBody obj = (ProvinceExcelBody) object;
                            provinceExcelBodies.add(obj);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext context) {
                        }
                    }, true);
            reader.read(new Sheet(2, 1, ProvinceExcelBody.class));
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
        if (CollectionUtils.isEmpty(provinceExcelBodies)) {
            return provinces;
        } else {
            for (ProvinceExcelBody provinceExcelBody : provinceExcelBodies) {
                Province province = new Province();
                province.setName(PubUtils.isBlank(provinceExcelBody.getName()) ? "" : provinceExcelBody.getName());
                province.setProvinceIndex(provinceExcelBody.getProvinceIndex() == null ? null : provinceExcelBody.getProvinceIndex().longValue());
                provinces.add(province);
            }
        }
        return provinces;
    }

    /**
     * 根据流获取出GDInformation的数据
     */
    private List<GDInformation> getGdInfomation(MultipartFile file) {
        List<GDInformation> gdInformations = new ArrayList<>();
        List<GDExcelBody> gdExcelBodies = new ArrayList<>();
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
            ExcelReader reader = new ExcelReader(inputStream, ExcelTypeEnum.XLSX, null,
                    new AnalysisEventListener() {
                        @Override
                        public void invoke(Object object, AnalysisContext context) {
                            GDExcelBody obj = (GDExcelBody) object;
                            gdExcelBodies.add(obj);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext context) {
                        }
                    }, true);
            reader.read(new Sheet(3, 1, GDExcelBody.class));
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
        if (CollectionUtils.isEmpty(gdExcelBodies)) {
            return gdInformations;
        } else {
            for (GDExcelBody gdExcelBody : gdExcelBodies) {
                GDInformation gdInformation = new GDInformation();
                gdInformation.setGdIndex(gdExcelBody.getGdIndex() == null ? null : gdExcelBody.getGdIndex().longValue());
                gdInformation.setName(PubUtils.isBlank(gdExcelBody.getName()) ? "" : gdExcelBody.getName());
                gdInformation.setProvinceIndex(gdExcelBody.getProvinceIndex() == null ? null : gdExcelBody.getProvinceIndex().longValue());
                gdInformations.add(gdInformation);
            }
        }
        return gdInformations;
    }

    /**
     * 根据流获取出subStation的数据
     */
    private List<SubStation> getSubstation(MultipartFile file) {
        List<SubStation> subStations = new ArrayList<>();
        List<SubStationExcelBody> subStationExcelBodies = new ArrayList<>();
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
            ExcelReader reader = new ExcelReader(inputStream, ExcelTypeEnum.XLSX, null,
                    new AnalysisEventListener() {
                        @Override
                        public void invoke(Object object, AnalysisContext context) {
                            SubStationExcelBody obj = (SubStationExcelBody) object;
                            subStationExcelBodies.add(obj);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext context) {
                        }
                    }, true);
            reader.read(new Sheet(4, 1, SubStationExcelBody.class));
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
        if (CollectionUtils.isEmpty(subStationExcelBodies)) {
            return subStations;
        } else {
            for (SubStationExcelBody subStationExcelBody : subStationExcelBodies) {
                SubStation subStation = new SubStation();
                subStation.setSubIndex(subStationExcelBody.getSubIndex() == null ? null : subStationExcelBody.getSubIndex().longValue());
                subStation.setGdIndex(subStationExcelBody.getGdIndex() == null ? null : subStationExcelBody.getGdIndex().longValue());
                subStation.setName(PubUtils.isBlank(subStationExcelBody.getName()) ? "" : subStationExcelBody.getName());
                subStations.add(subStation);
            }
        }
        return subStations;
    }

    /**
     * 根据流获取出device的数据
     */
    private List<Device> getDevice(MultipartFile file) throws Exception {
        List<Device> devices = new ArrayList<>();
        List<DeviceExcelBody> deviceExcelBodies = new ArrayList<>();
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
            ExcelReader reader = new ExcelReader(inputStream, ExcelTypeEnum.XLSX, null,
                    new AnalysisEventListener() {
                        @Override
                        public void invoke(Object object, AnalysisContext context) {
                            DeviceExcelBody obj = (DeviceExcelBody) object;
                            deviceExcelBodies.add(obj);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext context) {
                        }
                    }, true);
            reader.read(new Sheet(5, 1, DeviceExcelBody.class));
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
        if (CollectionUtils.isEmpty(deviceExcelBodies)) {
            return devices;
        } else {
            for (DeviceExcelBody deviceExcelBody : deviceExcelBodies) {
                Device device = new Device();
                device.setDevIndex(deviceExcelBody.getDevIndex() == null ? null : deviceExcelBody.getDevIndex().longValue());
                device.setGdIndex(deviceExcelBody.getGdIndex() == null ? null : deviceExcelBody.getGdIndex().longValue());
                device.setSubIndex(deviceExcelBody.getSubIndex() == null ? null : deviceExcelBody.getSubIndex().longValue());
                device.setName(PubUtils.isBlank(deviceExcelBody.getName()) ? "" : deviceExcelBody.getName());
                device.setStatus(deviceExcelBody.getStatus() == null ? null : deviceExcelBody.getStatus().intValue());
                device.setDevType(PubUtils.isBlank(deviceExcelBody.getDevType()) ? "" : deviceExcelBody.getDevType());
                device.setIp(PubUtils.isBlank(deviceExcelBody.getIp()) ? "" : deviceExcelBody.getIp());
                device.setLogonTime(PubUtils.isBlank(deviceExcelBody.getLogonTime()) ? null : PubUtils.string2Date(deviceExcelBody.getLogonTime(), "yyyy-MM-dd HH:mm:ss"));
                device.setUpdateTime(PubUtils.isBlank(deviceExcelBody.getUpdateTime()) ? null : PubUtils.string2Date(deviceExcelBody.getUpdateTime(), "yyyy-MM-dd HH:mm:ss"));
                device.setCallFlag(deviceExcelBody.getCallFlag() == null ? null : deviceExcelBody.getCallFlag().intValue());
                device.setNodeIndex(deviceExcelBody.getNodeIndex() == null ? null : deviceExcelBody.getNodeIndex().longValue());
                device.setPortId(deviceExcelBody.getPortId() == null ? null : deviceExcelBody.getPortId().longValue());
                device.setDevFlag(deviceExcelBody.getDevFlag() == null ? null : deviceExcelBody.getDevFlag().intValue());
                device.setSeries(PubUtils.isBlank(deviceExcelBody.getDevSeries()) ? "" : deviceExcelBody.getDevSeries());
                device.setKey(PubUtils.isBlank(deviceExcelBody.getDevKey()) ? "" : deviceExcelBody.getDevKey());
                device.setDevmodel(deviceExcelBody.getDevmodel() == null ? null : deviceExcelBody.getDevmodel().longValue());
                device.setDatatype(deviceExcelBody.getDatatype() == null ? null : deviceExcelBody.getDatatype().longValue());
                devices.add(device);
            }
        }
        return devices;
    }

    /**
     * 根据流获取出deviceDetail的数据
     */
    private List<DeviceDetailInfo> getDeviceDetail(MultipartFile file) throws Exception {
        List<DeviceDetailInfo> deviceDetails = new ArrayList<>();
        List<DeviceDetailExcelBody> deviceDetailExcelBodies = new ArrayList<>();
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
            ExcelReader reader = new ExcelReader(inputStream, ExcelTypeEnum.XLSX, null,
                    new AnalysisEventListener() {
                        @Override
                        public void invoke(Object object, AnalysisContext context) {
                            DeviceDetailExcelBody obj = (DeviceDetailExcelBody) object;
                            deviceDetailExcelBodies.add(obj);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext context) {
                        }
                    }, true);
            reader.read(new Sheet(6, 1, DeviceDetailExcelBody.class));
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
        if (CollectionUtils.isEmpty(deviceDetailExcelBodies)) {
            return deviceDetails;
        } else {
            for (DeviceDetailExcelBody deviceDetailExcelBody : deviceDetailExcelBodies) {
                DeviceDetailInfo deviceDetail = new DeviceDetailInfo();
                deviceDetail.setDevIndex(deviceDetailExcelBody.getDevIndex() == null ? null : deviceDetailExcelBody.getDevIndex().longValue());
                deviceDetail.setManufacturer(PubUtils.isBlank(deviceDetailExcelBody.getManufacturer()) ? "" : deviceDetailExcelBody.getManufacturer());
                deviceDetail.setCheckFlag(deviceDetailExcelBody.getCheckFlag() == null ? null : deviceDetailExcelBody.getCheckFlag().longValue());
                deviceDetail.setThisTimeCheck(PubUtils.isBlank(deviceDetailExcelBody.getThisTimeCheck()) ? null : PubUtils.string2Date(deviceDetailExcelBody.getThisTimeCheck(), "yyyy-MM-dd HH:mm:ss"));
                deviceDetail.setNextTimeCheck(PubUtils.isBlank(deviceDetailExcelBody.getNextTimeCheck()) ? null : PubUtils.string2Date(deviceDetailExcelBody.getNextTimeCheck(), "yyyy-MM-dd HH:mm:ss"));
                deviceDetails.add(deviceDetail);
            }
        }
        return deviceDetails;
    }

    /**
     * 根据流获取出subVoltage的数据
     */
    private List<SubVoltage> getSubVoltages(MultipartFile file) {
        List<SubVoltage> subVoltages = new ArrayList<>();
        List<SubVoltageExcelBody> subVoltageExcelBodies = new ArrayList<>();
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
            ExcelReader reader = new ExcelReader(inputStream, ExcelTypeEnum.XLSX, null,
                    new AnalysisEventListener() {
                        @Override
                        public void invoke(Object object, AnalysisContext context) {
                            SubVoltageExcelBody obj = (SubVoltageExcelBody) object;
                            subVoltageExcelBodies.add(obj);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext context) {
                        }
                    }, true);
            reader.read(new Sheet(7, 1, SubVoltageExcelBody.class));
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
        if (CollectionUtils.isEmpty(subVoltageExcelBodies)) {
            return subVoltages;
        } else {
            for (SubVoltageExcelBody subVoltageExcelBody : subVoltageExcelBodies) {
                SubVoltage subVoltage = new SubVoltage();
                subVoltage.setSubvIndex(subVoltageExcelBody.getSubvIndex() == null ? null : subVoltageExcelBody.getSubvIndex().longValue());
                subVoltage.setSubIndex(subVoltageExcelBody.getSubIndex() == null ? null : subVoltageExcelBody.getSubIndex().longValue());
                subVoltage.setDevIndex(subVoltageExcelBody.getDevIndex() == null ? null : subVoltageExcelBody.getDevIndex().longValue());
                subVoltage.setGdIndex(subVoltageExcelBody.getGdIndex() == null ? null : subVoltageExcelBody.getGdIndex().longValue());
                subVoltage.setName(PubUtils.isBlank(subVoltageExcelBody.getName()) ? "" : subVoltageExcelBody.getName());
                subVoltage.setSubvNum(subVoltageExcelBody.getSubvNum() == null ? null : subVoltageExcelBody.getSubvNum().intValue());
                subVoltage.setScale(PubUtils.isBlank(subVoltageExcelBody.getScale()) ? "" : subVoltageExcelBody.getScale());
                subVoltage.setSubvModel(subVoltageExcelBody.getSubvModel() == null ? null : subVoltageExcelBody.getSubvModel().longValue());
                subVoltages.add(subVoltage);
            }
        }
        return subVoltages;
    }

    /**
     * 根据流获取出line的数据
     */
    private List<Line> getLine(MultipartFile file) {
        List<Line> lines = new ArrayList<>();
        List<LineExcelBody> lineExcelBodies = new ArrayList<>();
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
            ExcelReader reader = new ExcelReader(inputStream, ExcelTypeEnum.XLSX, null,
                    new AnalysisEventListener() {
                        @Override
                        public void invoke(Object object, AnalysisContext context) {
                            LineExcelBody obj = (LineExcelBody) object;
                            lineExcelBodies.add(obj);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext context) {
                        }
                    }, true);
            reader.read(new Sheet(9, 1, LineExcelBody.class));
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
        if (CollectionUtils.isEmpty(lineExcelBodies)) {
            return lines;
        } else {
            for (LineExcelBody lineExcelBody : lineExcelBodies) {
                Line line = new Line();
                line.setLineIndex(lineExcelBody.getLineIndex() == null ? null : lineExcelBody.getLineIndex().longValue());
                line.setGdIndex(lineExcelBody.getGdIndex() == null ? null : lineExcelBody.getGdIndex().longValue());
                line.setSubIndex(lineExcelBody.getSubIndex() == null ? null : lineExcelBody.getSubIndex().longValue());
                line.setSubvIndex(lineExcelBody.getSubvIndex() == null ? null : lineExcelBody.getSubvIndex().longValue());
                line.setDevIndex(lineExcelBody.getDevIndex() == null ? null : lineExcelBody.getDevIndex().longValue());
                line.setName(PubUtils.isBlank(lineExcelBody.getName()) ? "" : lineExcelBody.getName());
                line.setPt1(lineExcelBody.getPt1() == null ? null : lineExcelBody.getPt1().floatValue());
                line.setPt2(lineExcelBody.getPt2() == null ? null : lineExcelBody.getPt2().floatValue());
                line.setCt1(lineExcelBody.getCt1() == null ? null : lineExcelBody.getCt1().floatValue());
                line.setCt2(lineExcelBody.getCt2() == null ? null : lineExcelBody.getCt2().floatValue());
                line.setDevcMp(lineExcelBody.getDevcMp() == null ? null : lineExcelBody.getDevcMp().floatValue());
                line.setDlcMp(lineExcelBody.getDlcMp() == null ? null : lineExcelBody.getDlcMp().floatValue());
                line.setJzcMp(lineExcelBody.getJzcMp() == null ? null : lineExcelBody.getJzcMp().floatValue());
                line.setXycMp(lineExcelBody.getXycMp() == null ? null : lineExcelBody.getXycMp().floatValue());
                line.setSubVNo(lineExcelBody.getSubVNo() == null ? null : lineExcelBody.getSubVNo().intValue());
                line.setScale(PubUtils.isBlank(lineExcelBody.getScale()) ? "" : lineExcelBody.getScale());
                line.setSubvName(PubUtils.isBlank(lineExcelBody.getSubvName()) ? "" : lineExcelBody.getSubvName());
                lines.add(line);
            }
        }
        return lines;
    }

    /**
     * 根据流获取出lineDetail的数据
     */
    private List<LineDetail> getLineDetail(MultipartFile file) throws Exception {
        List<LineDetail> lineDetails = new ArrayList<>();
        List<LineDetailExcelBody> lineDetailExcelBodies = new ArrayList<>();
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
            ExcelReader reader = new ExcelReader(inputStream, ExcelTypeEnum.XLSX, null,
                    new AnalysisEventListener() {
                        @Override
                        public void invoke(Object object, AnalysisContext context) {
                            LineDetailExcelBody obj = (LineDetailExcelBody) object;
                            lineDetailExcelBodies.add(obj);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext context) {
                        }
                    }, true);
            reader.read(new Sheet(8, 1, LineDetailExcelBody.class));
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
        if (CollectionUtils.isEmpty(lineDetailExcelBodies)) {
            return lineDetails;
        } else {
            for (LineDetailExcelBody lineDetailExcelBody : lineDetailExcelBodies) {
                LineDetail lineDetail = new LineDetail();
                lineDetail.setLineIndex(lineDetailExcelBody.getLineIndex() == null ? null : lineDetailExcelBody.getLineIndex().longValue());
                lineDetail.setGdIndex(lineDetailExcelBody.getGdIndex() == null ? null : lineDetailExcelBody.getGdIndex().longValue());
                lineDetail.setSubIndex(lineDetailExcelBody.getSubIndex() == null ? null : lineDetailExcelBody.getSubIndex().longValue());
                lineDetail.setLineName(PubUtils.isBlank(lineDetailExcelBody.getLineName()) ? "" : lineDetailExcelBody.getLineName());
                lineDetail.setPtType(lineDetailExcelBody.getPtType() == null ? null : lineDetailExcelBody.getPtType().intValue());
                lineDetail.setLastTime(PubUtils.isBlank(lineDetailExcelBody.getLastTime()) ? null : PubUtils.string2Date(lineDetailExcelBody.getLastTime(), "yyyy-MM-dd HH:mm:ss"));
                lineDetail.setTInterval(lineDetailExcelBody.getTinterval() == null ? null : lineDetailExcelBody.getTinterval().intValue());
                lineDetail.setLoadType(PubUtils.isBlank(lineDetailExcelBody.getLoadType()) ? "" : lineDetailExcelBody.getLoadType());
                lineDetail.setBusinessType(PubUtils.isBlank(lineDetailExcelBody.getBusinessType()) ? "" : lineDetailExcelBody.getBusinessType());
                lineDetail.setRemark(PubUtils.isBlank(lineDetailExcelBody.getRemark()) ? "" : lineDetailExcelBody.getRemark());
                lineDetails.add(lineDetail);
            }
        }
        return lineDetails;
    }

    /**
     * 根据流获取出暂降事件列表的数据
     */
    private List<EventDetail> getEventDetail(MultipartFile file) throws Exception {
        InputStream inputStream = file.getInputStream();
        List<EventDetail> eventDetails = new ArrayList<>();
        List<EventDetailExcelBody> eventDetailExcelBodies = new ArrayList<>();
        try {
            ExcelReader reader = new ExcelReader(inputStream, ExcelTypeEnum.XLSX, null,
                    new AnalysisEventListener() {
                        @Override
                        public void invoke(Object object, AnalysisContext context) {
                            EventDetailExcelBody obj = (EventDetailExcelBody) object;
                            eventDetailExcelBodies.add(obj);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext context) {
                        }
                    }, true);
            reader.read(new Sheet(1, 1, EventDetailExcelBody.class));
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }

        if (CollectionUtils.isEmpty(eventDetailExcelBodies)) {
            return eventDetails;
        } else {
            for (EventDetailExcelBody eventDetailExcelBody : eventDetailExcelBodies) {
                EventDetail eventDetail = new EventDetail();
                eventDetail.setEventDetailIndex(eventDetailExcelBody.getEventDetailIndex());
                eventDetail.setLineId(eventDetailExcelBody.getLineId().longValue());
                eventDetail.setTimeId(PubUtils.string2Date(eventDetailExcelBody.getTimeId(), "yyyy-MM-dd HH:mm:ss"));
                eventDetail.setMs(eventDetailExcelBody.getMs().longValue());
                eventDetail.setDescribe(PubUtils.isBlank(eventDetailExcelBody.getDescribe()) ? "" : eventDetailExcelBody.getDescribe());
                eventDetail.setWaveType(eventDetailExcelBody.getWaveType().intValue());
                eventDetail.setPersistTime(eventDetailExcelBody.getPersistTime().floatValue());
                eventDetail.setEventValue(eventDetailExcelBody.getEventValue().floatValue());
                eventDetail.setEventReason(PubUtils.isBlank(eventDetailExcelBody.getEventReason()) ? "" : eventDetailExcelBody.getEventReason());
                eventDetail.setEventType(PubUtils.isBlank(eventDetailExcelBody.getEventType()) ? "" : eventDetailExcelBody.getEventType());
                eventDetail.setEventassIndex(PubUtils.isBlank(eventDetailExcelBody.getEventassIndex()) ? "" : eventDetailExcelBody.getEventassIndex());
                eventDetail.setDqTime(eventDetailExcelBody.getDqTime() == null ? null : eventDetailExcelBody.getDqTime().floatValue());
                eventDetail.setDealTime(PubUtils.isBlank(eventDetailExcelBody.getDealTime()) ? null : PubUtils.string2Date(eventDetailExcelBody.getDealTime(), "yyyy-MM-dd HH:mm:ss"));
                eventDetail.setNum(eventDetailExcelBody.getNum() == null ? null : eventDetailExcelBody.getNum().intValue());
                eventDetail.setFileFlag(PubUtils.isBlank(eventDetailExcelBody.getFileFlag()) ? "" : eventDetailExcelBody.getFileFlag());
                eventDetail.setDealFlag(PubUtils.isBlank(eventDetailExcelBody.getDealFlag()) ? "" : eventDetailExcelBody.getDealFlag());
                eventDetail.setFirstTime(eventDetailExcelBody.getFirstTime() == null ? null : PubUtils.string2Date(eventDetailExcelBody.getFirstTime(), "yyyy-MM-dd HH:mm:ss"));
                eventDetail.setFirstType(PubUtils.isBlank(eventDetailExcelBody.getFirstType()) ? "" : eventDetailExcelBody.getFirstType());
                eventDetail.setFirstMs(eventDetailExcelBody.getMs() == null ? null : eventDetailExcelBody.getMs().intValue());
                eventDetail.setWaveName(PubUtils.isBlank(eventDetailExcelBody.getWaveName()) ? "" : eventDetailExcelBody.getWaveName());
                eventDetail.setEnergy(eventDetailExcelBody.getEnergy() == null ? null : eventDetailExcelBody.getEnergy().floatValue());
                eventDetail.setSeverity(eventDetailExcelBody.getSeverity() == null ? null : eventDetailExcelBody.getSeverity().floatValue());
                eventDetails.add(eventDetail);
            }
        }
        return eventDetails;
    }


    /**
     * 区域--》区域分析
     *
     * @param startTime 起始时间
     * @param endTime   截止时间
     */
    @Override
    public ReasonStatisc getVolStatisticsCounts(String area, Date startTime, Date endTime) {
        ReasonStatisc rs = new ReasonStatisc();
        List<Integer> linesIndexTemp = new ArrayList<>();
        //事件总数
        Integer sum;
        List<AreaGeneralData> areaGeneral = userUtil.getAreaDataByInfoRun(area);
        rs.setCityName(userUtil.getDeptsByIndex(area).getArea());
        for (AreaGeneralData areaGeneralData : areaGeneral) {
            linesIndexTemp.addAll(areaGeneralData.getLineIndexs());
        }
        //此处需要对监测点排重，避免自定义的监测点查出重复的暂降事件
        List<Integer> linesIndex = new ArrayList<>(new HashSet(linesIndexTemp));
        List<StatisticsEventDetail> detail = new ArrayList<>();
        if (linesIndex.isEmpty()) {
            detail = null;
        } else {
            //分片1000个监测点
            if (linesIndex.size() > 1000) {
                //需要循环的次数
                int times = ((linesIndex.size() % 1000 == 0) ? linesIndex.size() / 1000 : (linesIndex.size() / 1000 + 1));
                for (int i = 1; i <= times; i++) {
                    if (linesIndex.size() > 1000) {
                        List<Integer> temp = linesIndex.subList(0, 1000);
                        List<StatisticsEventDetail> tempList = eventDetailMapper.queryEventDetail(startTime, endTime, temp);
                        detail.addAll(tempList);
                        temp.clear();
                    } else {
                        List<StatisticsEventDetail> tempList = eventDetailMapper.queryEventDetail(startTime, endTime, linesIndex);
                        detail.addAll(tempList);
                    }
                }
            } else {
                detail = eventDetailMapper.queryEventDetail(startTime, endTime, linesIndex);
            }
        }
        //初始化集合
        List<VoltageReason> reasons = initReason();
        List<VoltageType> types = initType();
        if (CollectionUtils.isEmpty(detail)) {
            reasons = null;
            types = null;
        } else {
            for (StatisticsEventDetail d : detail) {
                for (VoltageReason volR : reasons) {
                    if (volR.getReason().equalsIgnoreCase(d.getEventReason())) {
                        volR.setTimes(volR.getTimes() + 1);
                        if (d.getEventReason().equalsIgnoreCase("短路故障")) {
                            for (VoltageType volT : types) {
                                if (volT.getType().equalsIgnoreCase(d.getEventType())) {
                                    volT.setTimes(volT.getTimes() + 1);
                                    break;
                                }
                            }
                        }
                        break;
                    }
                }
            }
        }
        //事件总次数
        if (CollectionUtils.isEmpty(detail)) {
            sum = 0;
        } else {
            sum = detail.size();
        }
        rs.setDetail(detail);
        rs.setReasons(reasons);
        rs.setTotalTimes(sum);
        rs.setTypes(types);
        return rs;
    }


    /**
     * 初始化原因集合
     */
    List<VoltageReason> initReason() {
        List<VoltageReason> v = new ArrayList<>();
        List<DicData> voltageReason = redisCacheUtil.getVoltageReason();
        for (DicData dicData : voltageReason) {
            VoltageReason temp = new VoltageReason();
            temp.setReason(dicData.getDicName());
            temp.setTimes(0);
            v.add(temp);
        }
        return v;
    }

    /**
     * 初始化类型集合
     */
    List<VoltageType> initType() {
        List<VoltageType> v = new ArrayList<>();
        List<String> names = new ArrayList<>();
        List<DicData> voltageType = redisCacheUtil.getVoltageType();
        for (DicData dicData : voltageType) {
            if (!names.contains(dicData.getBackUp())) {
                names.add(dicData.getBackUp());
            }
        }
        for (String name : names) {
            VoltageType temp = new VoltageType();
            temp.setType(name);
            temp.setTimes(0);
            v.add(temp);
        }
        return v;
    }



    /**
     *获取暂降事件
     * @date 2021/1/22
     */
    @Override
    public List<EventDetail> getVolList(Date startTime, Date endTime, String area, String type,BigDecimal minfuzhi,
                                        BigDecimal maxfuzhi, BigDecimal mintime, BigDecimal maxtime,
                                        BigDecimal minseverity, BigDecimal maxseverity, List<String> eventType, List<String> eventReason, List<Integer> triggerType, Integer fileflag) {
        List<EventDetail> evevtDetailList = new ArrayList<>();
        List<Integer> linesIndex;
        if (type.equalsIgnoreCase("online")) {
            //根据区域获取在线装置的所有监测点
            linesIndex = userUtil.getAllLineIndexs(area);
        } else {
            //根据区域获取离线线装置的所有监测点
            linesIndex = userUtil.getAllOffLineIndexs(area);
        }
        if (CollectionUtils.isEmpty(linesIndex)) {
            return null;
        }
        //分片1000个监测点
        if (linesIndex.size() > 1000) {
            //需要循环的次数
            int times = ((linesIndex.size() % 1000 == 0) ? linesIndex.size() / 1000 : (linesIndex.size() / 1000 + 1));
            for (int i = 1; i <= times; i++) {
                if (linesIndex.size() > 1000) {
                    List<Integer> temp = linesIndex.subList(0, 1000);
                    List<EventDetail> tempList = eventDetailMapper.queryVoltageList(startTime, endTime, temp, null,minfuzhi,maxfuzhi,mintime,maxtime,minseverity,maxseverity,eventType,eventReason,triggerType,fileflag);
                    evevtDetailList.addAll(tempList);
                    temp.clear();
                } else {
                    List<EventDetail> tempList;
                    tempList = eventDetailMapper.queryVoltageList(startTime, endTime, linesIndex, null,minfuzhi,maxfuzhi,mintime,maxtime,minseverity,maxseverity,eventType,eventReason,triggerType,fileflag);
                    evevtDetailList.addAll(tempList);
                }
            }
        } else {
            evevtDetailList = eventDetailMapper.queryVoltageList(startTime, endTime, linesIndex, null,minfuzhi,maxfuzhi,mintime,maxtime,minseverity,maxseverity,eventType,eventReason,triggerType,fileflag);
        }
        if (CollectionUtils.isEmpty(evevtDetailList)) {
            return null;
        } else {
            return evevtDetailList;
        }
    }



    /**
     * 获取前台需要的暂降列表数据，分页尺寸是（200）
     */
    @Override
    public List<EventDetail> getVolListByType(Date startTime, Date endTime, String area, String type, String waveType,BigDecimal minfuzhi,
                                              BigDecimal maxfuzhi, BigDecimal mintime, BigDecimal maxtime,
                                              BigDecimal minseverity, BigDecimal maxseverity, List<String> eventType, List<String> eventReason, List<Integer> triggerType, Integer fileflag) {
        List<EventDetail> evevtDetailList = new ArrayList<>();
        List<Integer> linesIndex;
        if (type.equalsIgnoreCase("online")) {
            //根据区域获取在线装置的所有监测点
            linesIndex = userUtil.getAllLineIndexs(area);
        } else {
            //根据区域获取离线线装置的所有监测点
            linesIndex = userUtil.getAllOffLineIndexs(area);
        }
        if (CollectionUtils.isEmpty(linesIndex)) {
            return null;
        }
        //分片1000个监测点
        if (linesIndex.size() > 1000) {
            //需要循环的次数
            int times = ((linesIndex.size() % 1000 == 0) ? linesIndex.size() / 1000 : (linesIndex.size() / 1000 + 1));
            for (int i = 1; i <= times; i++) {
                if (linesIndex.size() > 1000) {
                    List<Integer> temp = linesIndex.subList(0, 1000);
                    List<EventDetail> tempList = eventDetailMapper.queryVoltageList(startTime, endTime, temp, waveType,minfuzhi,maxfuzhi,mintime,maxtime,minseverity,maxseverity,eventType,eventReason,triggerType,fileflag);
                    evevtDetailList.addAll(tempList);
                    temp.clear();
                } else {
                    List<EventDetail> tempList;
                    tempList = eventDetailMapper.queryVoltageList(startTime, endTime, linesIndex, waveType,minfuzhi,maxfuzhi,mintime,maxtime,minseverity,maxseverity,eventType,eventReason,triggerType,fileflag);
                    evevtDetailList.addAll(tempList);
                }
            }
        } else {
            evevtDetailList = eventDetailMapper.queryVoltageList(startTime, endTime, linesIndex, waveType,minfuzhi,maxfuzhi,mintime,maxtime,minseverity,maxseverity,eventType,eventReason,triggerType,fileflag);
        }
        if (CollectionUtils.isEmpty(evevtDetailList)) {
            return null;
        } else {
            return evevtDetailList;
        }
    }

    @Override
    public List<List> getrunevent() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<List> eventList = new ArrayList<List>();
        List<AreaGeneralData> areaGeneral = userUtil.getAreaGeneral();
        List<Integer> list = new ArrayList<>();
        List<Integer> list1 = new ArrayList<>();
        for (AreaGeneralData data : areaGeneral) {
            Integer lineId = 0;
            list = data.getLineIndexs();// 获取监测点ID
            if (list.isEmpty() == false) {
                for (int i = 0; i < list.size(); i++) {
                    lineId = list.get(i);
                    list1.add(lineId);
                }
            }
        }
        List<Integer> lineIndexsTemp = new ArrayList<>(list1);
        List<EventDetail> eventdetail = new ArrayList<>();
        if (lineIndexsTemp.size() > 100) {
            int size = lineIndexsTemp.size() / 100 + 1;
            for (int i = 0; i < size; i++) {
                if (lineIndexsTemp.size() > 100) {
                    List<Integer> tempLineIndexs = lineIndexsTemp.subList(0, 100);
                    List<EventDetail> tmplist = eventDetailMapper.getrunevent(tempLineIndexs);
                    eventdetail.addAll(tmplist);
                    tempLineIndexs.clear();
                } else {
                    List<EventDetail> tmplist = eventDetailMapper.getrunevent(lineIndexsTemp);
                    eventdetail.addAll(tmplist);
                }
            }
        } else {
            eventdetail = eventDetailMapper.getrunevent(lineIndexsTemp);
        }
        if (eventdetail.isEmpty()) {
            return eventList;
        } else {
            for (EventDetail detail : eventdetail) {
                List<String> temp = new ArrayList<String>();
                temp.add(detail.getLineName());
                temp.add(sdf.format(detail.getTimeId()));
                temp.add(detail.getEventType());
                eventList.add(temp);
            }
        }
        return eventList;
    }

    /**
     * 根据事件索引查询事件
     *
     * @param index 事件索引
     */
    @Override
    public EventDetail selectByIndex(String index) {
        Example example = new Example(EventDetail.class);
        example.createCriteria().andEqualTo("eventDetailIndex", index);
        List<EventDetail> eventDetail;
        eventDetail = eventDetailMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(eventDetail)) {
            return null;
        }
        return eventDetail.get(0);
    }

    @Override
    public List<EventDetail> queryZj(String startTime, String endTime,
                                     String start, String end,
                                     Long linesIndex) {
        return eventDetailMapper.queryZj(startTime, endTime, start, end, linesIndex);
    }

    @Override
    public List<EventEigDetail> eventDetailEigenvalue(String eventDetailIndex) throws Exception {
        List<EventEigDetail> eventInfoDetails = new ArrayList<>();
        EntityAdvancedData entityAdvancedData = iWaveService.analysis(eventDetailIndex);

        //根据事件获取监测点接线方式
        Integer pttype = iWaveService.getPtType(eventDetailIndex);

        if (entityAdvancedData.backNumber != -1) {
            backNumber = entityAdvancedData.backNumber;
            for (int i = 0; i < entityAdvancedData.backNumber; i++) {
                EventEigDetail eventEigDetail = new EventEigDetail();
                eventEigDetail.setHold_time_dq(entityAdvancedData.evt_buf[i].hold_time_dq * 1000);
                eventEigDetail.setPow_a(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].POW_a));
                eventEigDetail.setPow_b(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].POW_b));
                eventEigDetail.setPow_c(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].POW_c));

                eventEigDetail.setVoltagechange_Va(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].Voltagechange_Va / 1000));
                eventEigDetail.setVoltagechange_Vb(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].Voltagechange_Vb / 1000));
                eventEigDetail.setVoltagechange_Vc(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].Voltagechange_Vc / 1000));


                eventEigDetail.setUa_min(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].ua_min[0]));
                eventEigDetail.setUb_min(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].ub_min[0]));
                eventEigDetail.setUc_min(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].ua_min[0]));

                eventEigDetail.setAngle_diff_ap(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].angle_diff_ap[0]));
                eventEigDetail.setAngle_diff_bp(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].angle_diff_bp[0]));
                eventEigDetail.setAngle_diff_cp(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].angle_diff_cp[0]));

                eventEigDetail.setBph_max_value(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].bph_max_value[0]));
                eventEigDetail.setSagReason(entityAdvancedData.sagReason[0]);//暂降原因，暂降原因都一样
                eventEigDetail.setSagType(entityAdvancedData.sagType[i]);//暂降类型
                eventInfoDetails.add(eventEigDetail);
                eventEigDetail.setPttype(pttype);
            }
        } else {
            backNumber = 0;
            eventInfoDetails = null;
        }
        //eventInfoDetails = eventInfoMapper.eventDetailEigenvalue(eventDetailIndex);
        return eventInfoDetails;
    }

    @Override
    public EventInfoDetail eventDetailBaseInfoByIndex(String eventdetailIndex) {
        EventInfoDetail eventInfoDetails = new EventInfoDetail();
        try {
            eventInfoDetails = eventDetailMapper.eventDetailBaseInfoByIndex(eventdetailIndex);
        } catch (Exception e) {
            logger.error("查询暂降事件详情发生异常，异常是" + e.getMessage());
        }
        return eventInfoDetails;
    }
}
