package com.pqs9900.serviceImpl.webtool;

import java.io.*;
import java.net.URLDecoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileWriter;
import com.njcn.mapper.configuration.LineDetailMapper;
import com.njcn.mapper.data.EventDetailMapper;
import com.njcn.pojo.commons.WaveData;
import com.njcn.pojo.commons.wave.AnalyWaveModel;
import com.njcn.pojo.configuration.LineDetail;
import com.njcn.pojo.data.EventDetail;
import com.njcn.service.configuration.DeviceService;
import com.njcn.service.configuration.ILineService;
import com.njcn.utils.*;
import com.njcn.utils.redis.JedisManager;
import org.apache.commons.collections4.ListUtils;
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 com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.njcn.mapper.configuration.LineMapper;
import com.njcn.mapper.configuration.TreeMapper;
import com.njcn.pojo.commons.device.Tree;
import com.njcn.pojo.configuration.Line;
import com.pqs9900.mapper.webtool.CsvDataMapper;
import com.pqs9900.service.webtool.CsvDataService;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import tk.mybatis.mapper.entity.Example;

/**
 * @Description
 * @Author cdf
 * @Date 2020/6/3 15:04
 **/
@Service
public class CsvDataServiceImpl implements CsvDataService {

    private static final Logger logger = LoggerFactory.getLogger(CsvDataServiceImpl.class);
    @Autowired
    private CsvDataMapper csvDataMapper;

    @Resource
    private LineMapper lineMapper;
    @Resource
    private TreeMapper treeMapper;
    @Autowired
    private UserUtil userUtil;
    @Autowired
    private AppConfig appConfig;


    @Autowired
    private EventDetailMapper eventDetailMapper;

    @Autowired
    private ILineService lineService;

    @Autowired
    private DeviceService deviceService;


    @Autowired
    private LineDetailMapper lineDetailMapper;


    @Override
    public Map<String, Object> getAllInfo(Integer lineid, Integer page, Integer pageSize, Date beginTime, Date endTime) {


        // 设置表头
        String[] heade = DETAIL_HEAD_NAME_LIST;

        PageHelper.startPage(page, pageSize);
        HashMap<String, Object> map = new HashMap();
        List<Map<String, Object>> list = csvDataMapper.findAll(lineid, beginTime, endTime);
        PageInfo pageInfo = new PageInfo<>(list);
        map.put("heade", heade);
        map.put("pageInfo", pageInfo);
        return map;
    }

    @Override
    public String getCsvAsSession(Integer lineid, Date beginTime, Date endTime, HttpServletResponse response, HttpServletRequest request) throws IOException {
        HttpSession session = request.getSession();
        session.removeAttribute("percent");
        session.setAttribute("percent", 3);
        List<Map<String, Object>> lists = csvDataMapper.findAll(lineid, beginTime, endTime);
        session.setAttribute("percent", 85);
        // 导出到表格
        if (lists == null || lists.size() == 0) {
            session.setAttribute("percent", -1);
            return "数据为空";
        }

        // 设置表头
        String[] heade = DETAIL_HEAD_NAME_LIST;
        session.setAttribute("percent", 90);

        // 文件导出
        try {
            OutputStream os = response.getOutputStream();
            responseSetProperties(response);
            doExport(os, lists, heade);
            session.setAttribute("percent", 100);
            os.close();
        } catch (Exception e) {
            logger.error("产生了异常，异常是" + e.getMessage());
            // 重置response
        }
        return null;
    }


    /**
     * @Author chendaofei
     * @Description 批量导出csv
     * @Date 13:40 2020/4/8
     **/
    @Override
    public String getCsvBatch(List<Integer> list, Date beginTime, Date endTime, HttpServletResponse response) throws IOException {
        //判断是否监测点没有数据
        for (Integer lineid : list) {
            Integer count = csvDataMapper.checkIsExist(lineid, beginTime, endTime);
            if (count == 0) {
                return lineid.toString();
            }
        }
        return "存在数据";
    }


    /**
     * @Author chendaofei
     * @Description 设置响应
     * @Date 9:16 2020/4/7
     **/
    public static void responseSetProperties(HttpServletResponse response) throws UnsupportedEncodingException {
        // 读取字符编码
        String utf = "UTF-8";

        // 设置响应
        response.setContentType("application/csv");
        response.setCharacterEncoding(utf);
        response.setHeader("Pragma", "public");
        response.setHeader("Cache-Control", "max-age=30");
        response.setHeader("Content-Disposition", "attachment");

    }

    /**
     * @Author chendaofei
     * @Description 导出文件
     * @Date 9:15 2020/4/7
     **/
    public void doExport(OutputStream out, List<Map<String, Object>> list, String... header) throws IOException {
        try {
            int index = 1;
            // 保证线程安全
            StringBuffer buf = new StringBuffer();
            buf.append("序号").append(",");
            // 组装表头
            for (String title : header) {
                buf.append(title).append(",");
            }
            buf.append("\r\n");

            // 组装数据
            if (list != null && list.size() != 0) {
                SimpleDateFormat fo = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                for (Map<String, Object> data : list) {
                    buf.append(index).append(",");
                    for (String key : header) {
                        if (key.equals("TIMEID")) {
                            String tt = fo.format(data.get(key));
                            tt = XssFilterUtil.dealString(tt);
                            buf.append("\t" + tt + "\t").append(",");
                        } else {
                            buf.append(formatObject(data.get(key))).append(",");
                        }
                    }
                    buf.append("\r\n");
                    index++;
                }
            }

            // 写出响应
            out.write(XssFilterUtil.dealString(buf.toString()).getBytes("GBK"));
            out.flush();


        } catch (IOException e) {
            logger.error("产生了异常，异常是" + e.getMessage());
        }
    }


    @Override
    public Map<String, Object> flushProgress(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> map = null;
        //说明导出程序开始运行
        try {
            map = new HashMap();
            Integer percent = 0;
            HttpSession session = request.getSession();
            percent = Integer.valueOf(session.getAttribute("percent").toString());
            if (percent > 2 && percent < 90) {
                percent++;
                session.setAttribute("percent", percent);
            }

            map.put("percent", percent);
        } catch (Exception e) {
            logger.error("产生了异常，异常是" + e.getMessage());
        }
        return map;
    }


    public static final String[] DETAIL_HEAD_NAME_LIST = {"TIMEID", "电压总谐波畸变率A相最大值", "电压总谐波畸变率B相最大值", "电压总谐波畸变率C相最大值",
            "电压总谐波畸变率A相95值", "电压总谐波畸变率B相95值", "电压总谐波畸变率C相95值", "电压有效值A相平均值", "电压有效值B相平均值", "电压有效值C相平均值",
            "电压有效值A相最大值", "电压有效值B相最大值", "电压有效值C相最大值", "电流有效值A相平均值", "电流有效值B相平均值", "电流有效值C相平均值",
            "电流有效值A相最大值", "电流有效值B相最大值", "电流有效值C相最大值", "电压偏差A相平均值", "电压偏差B相平均值",
            "电压偏差C相平均值", "电压偏差A相最大值",
            "电压偏差B相最大值", "电压偏差C相最大值", "电压偏差A相95值", "电压偏差B相95值", "电压偏差C相95值", "有功功率平均值", "有功功率最小值", "有功功率最大值",
            "无功功率平均值", "无功功率最小值", "无功功率最大值", "视在功率平均值", "视在功率最小值", "视在功率最大值",
            "谐波电压含有率3次A相平均值", "谐波电压含有率3次B相平均值", "谐波电压含有率3次C相平均值", "谐波电压含有率3次A相最大值",
            "谐波电压含有率3次B相最大值", "谐波电压含有率3次C相最大值", "谐波电压含有率3次A相95值", "谐波电压含有率3次B相95值",
            "谐波电压含有率3次C相95值", "谐波电压含有率5次A相平均值", "谐波电压含有率5次B相平均值", "谐波电压含有率5次C相平均值",
            "谐波电压含有率5次A相最大值", "谐波电压含有率5次B相最大值", "谐波电压含有率5次C相最大值", "谐波电压含有率5次A相95值",
            "谐波电压含有率5次B相95值", "谐波电压含有率5次C相95值", "谐波电压含有率7次A相平均值", "谐波电压含有率7次B相平均值",
            "谐波电压含有率7次C相平均值", "谐波电压含有率7次A相最大值", "谐波电压含有率7次B相最大值", "谐波电压含有率7次C相最大值",
            "谐波电压含有率7次A相95值", "谐波电压含有率7次B相95值", "谐波电压含有率7次C相95值", "谐波电压含有率9次A相平均值",
            "谐波电压含有率9次B相平均值", "谐波电压含有率9次C相平均值", "谐波电压含有率9次A相最大值", "谐波电压含有率9次B相最大值",
            "谐波电压含有率9次C相最大值", "谐波电压含有率9次A相95值", "谐波电压含有率9次B相95值", "谐波电压含有率9次C相95值",
            "谐波电压含有率11次A相平均值", "谐波电压含有率11次B相平均值", "谐波电压含有率11次C相平均值", "谐波电压含有率11次A相最大值",
            "谐波电压含有率11次B相最大值", "谐波电压含有率11次C相最大值", "谐波电压含有率11次A相95值", "谐波电压含有率11次B相95值",
            "谐波电压含有率11次C相95值", "谐波电压含有率13次A相平均值", "谐波电压含有率13次B相平均值", "谐波电压含有率13次C相平均值",
            "谐波电压含有率13次A相最大值", "谐波电压含有率13次B相最大值", "谐波电压含有率13次C相最大值", "谐波电压含有率13次A相95值",
            "谐波电压含有率13次B相95值", "谐波电压含有率13次C相95值", "谐波电压含有率15次A相平均值", "谐波电压含有率15次B相平均值",
            "谐波电压含有率15次C相平均值", "谐波电压含有率15次A相最大值", "谐波电压含有率15次B相最大值", "谐波电压含有率15次C相最大值",
            "谐波电压含有率15次A相95值", "谐波电压含有率15次B相95值", "谐波电压含有率15次C相95值", "谐波电压含有率25次A相平均值",
            "谐波电压含有率25次B相平均值", "谐波电压含有率25次C相平均值", "谐波电压含有率25次A相最大值", "谐波电压含有率25次B相最大值",
            "谐波电压含有率25次C相最大值", "谐波电压含有率25次A相95值", "谐波电压含有率25次B相95值", "谐波电压含有率25次C相95值",
            "谐波电流幅值3次A相平均值", "谐波电流幅值3次B相平均值", "谐波电流幅值3次C相平均值", "谐波电流幅值3次A相最大值", "谐波电流幅值3次B相最大值",
            "谐波电流幅值3次C相最大值", "谐波电流幅值3次A相95值", "谐波电流幅值3次B相95值", "谐波电流幅值3次C相95值", "谐波电流幅值5次A相平均值",
            "谐波电流幅值5次B相平均值", "谐波电流幅值5次C相平均值", "谐波电流幅值5次A相最大值", "谐波电流幅值5次B相最大值", "谐波电流幅值5次C相最大值",
            "谐波电流幅值5次A相95值", "谐波电流幅值5次B相95值", "谐波电流幅值5次C相95值", "谐波电流幅值7次A相平均值", "谐波电流幅值7次B相平均值",
            "谐波电流幅值7次C相平均值", "谐波电流幅值7次A相最大值", "谐波电流幅值7次B相最大值", "谐波电流幅值7次C相最大值", "谐波电流幅值7次A相95值",
            "谐波电流幅值7次B相95值", "谐波电流幅值7次C相95值", "谐波电流幅值9次A相平均值", "谐波电流幅值9次B相平均值", "谐波电流幅值9次C相平均值",
            "谐波电流幅值9次A相最大值", "谐波电流幅值9次B相最大值", "谐波电流幅值9次C相最大值", "谐波电流幅值9次A相95值", "谐波电流幅值9次B相95值",
            "谐波电流幅值9次C相95值", "谐波电流幅值11次A相平均值", "谐波电流幅值11次B相平均值", "谐波电流幅值11次C相平均值", "谐波电流幅值11次A相最大值",
            "谐波电流幅值11次B相最大值", "谐波电流幅值11次C相最大值", "谐波电流幅值11次A相95值", "谐波电流幅值11次B相95值", "谐波电流幅值11次C相95值",
            "谐波电流幅值13次A相平均值", "谐波电流幅值13次B相平均值", "谐波电流幅值13次C相平均值", "谐波电流幅值13次A相最大值", "谐波电流幅值13次B相最大值",
            "谐波电流幅值13次C相最大值", "谐波电流幅值13次A相95值", "谐波电流幅值13次B相95值", "谐波电流幅值13次C相95值", "谐波电流幅值15次A相平均值",
            "谐波电流幅值15次B相平均值", "谐波电流幅值15次C相平均值", "谐波电流幅值15次A相最大值", "谐波电流幅值15次B相最大值", "谐波电流幅值15次C相最大值",
            "谐波电流幅值15次A相95值", "谐波电流幅值15次B相95值", "谐波电流幅值15次C相95值", "谐波电流幅值25次A相平均值", "谐波电流幅值25次B相平均值",
            "谐波电流幅值25次C相平均值", "谐波电流幅值25次A相最大值", "谐波电流幅值25次B相最大值", "谐波电流幅值25次C相最大值", "谐波电流幅值25次A相95值",
            "谐波电流幅值25次B相95值", "谐波电流幅值25次C相95值", "电压负序不平衡度平均值", "电压负序不平衡度最大值", "电压负序不平衡度95值", "频率平均值",
            "频率最大值", "频率95值", "A相短闪平均值", "B相短闪平均值", "C相短闪平均值"};


    /**
     * @Author chendaofei
     * @Description 数据完整性手动操作
     * @Date 9:21 2020/6/5
     **/
    @Override
    public String startHistoryTask(Integer lineNo, Date startTime, Date endTime) {
        Long conTime = 86400000L;
        try {
            //判断是一天还是多天
            Long begins = startTime.getTime();
            Long ends = endTime.getTime();
            if (ends - begins <= conTime) {
                //一天
                csvDataMapper.startHistoryTask(lineNo, startTime, endTime);
            } else {
                //非一天
                for (Long i = begins; i < ends; i += conTime) {
                    Date be = new Date(i);
                    Long en = i + conTime;
                    Date end = new Date(en);
                    csvDataMapper.startHistoryTask(lineNo, be, end);
                }

            }
        } catch (Exception e) {
            return "执行失败";
        }
        return "执行成功";
    }


    @Override
    public List<Tree> getTree() {
        String dky = "电网拓扑";

        int pIdNumber = Integer.parseInt(appConfig.getPidNumber());

        List<Tree> list = new ArrayList<>();

        List<Integer> index = userUtil.listLine();

        if (index.size() == 0) {
            Tree dto = new Tree();
            dto.setId(100);
            dto.setNodeType(0);
            dto.setpId(0);
            dto.setPpId(0);
            dto.setName(dky);
            list.add(dto);
            return list;
        } else {
            Tree dt = new Tree();
            dt.setId(100);
            dt.setNodeType(0);
            dt.setpId(0);
            dt.setPpId(0);
            dt.setName(dky);
            list.add(dt);


            List<List<Integer>> partList = ListUtils.partition(index,1000);
            List<Tree> proInfo = new ArrayList<>();
            List<Tree> gdInfo = new ArrayList<>();
            List<Tree> subInfo = new ArrayList<>();
            List<Tree> devInfo = new ArrayList<>();
            List<Tree> subvInfo = new ArrayList<>();
            List<Tree> lineInfo = new ArrayList<>();



            for(List<Integer> ids : partList) {
                List<Tree> proInfoTem = treeMapper.getTreeProInfo(ids);
                List<Tree> gdInfoTem = treeMapper.getTreeGdInfoToWebTool(ids);
                List<Tree> subInfoTem = treeMapper.getTreeSubInfoToWebTool(ids);
                List<Tree> devInfoTem = new ArrayList<>();
                if (appConfig.getSysType().equalsIgnoreCase(appConfig.getSysTypeWt())) {
                    devInfo = treeMapper.getWTTreeDevInfo(ids);
                } else {
                    devInfo = treeMapper.getZTTreeDevInfo(ids);
                }
                List<Tree> subvInfoTem = treeMapper.getNodeTreeSubvInfo(ids);
                List<Tree> lineInfoTem = treeMapper.getLineInfoToWebTool(ids);

                proInfo.addAll(proInfoTem);
                gdInfo.addAll(gdInfoTem);
                subInfo.addAll(subInfoTem);
                devInfo.addAll(devInfoTem);
                subvInfo.addAll(subvInfoTem);
                lineInfo.addAll(lineInfoTem);
            }
            if (proInfo == null || gdInfo == null || subInfo == null || devInfo == null || subvInfo == null
                    || lineInfo == null) {
                return list;
            }

            Map<Integer, Integer> value0 = new HashMap<Integer, Integer>();
            int p0 = pIdNumber;
            for (int i = 0; i < proInfo.size(); i++) {
                Tree dto = new Tree();
                dto.setId(++p0);
                dto.setName(userUtil.getDicnameByIndex(proInfo.get(i).getName()));
                dto.setpId(100);
                dto.setPpId(100);
                dto.setNodeIndex(proInfo.get(i).getNodeIndex());
                dto.setNodeType(1);

                int proIndex = proInfo.get(i).getNodeIndex();
                List<Line> lines = lineMapper.getLinesByPro(proIndex);
                List<Integer> indexs = new ArrayList<>();
                for (int n = 0; n < lines.size(); n++) {
                    indexs.add(lines.get(n).getLineIndex().intValue());
                }
                list.add(dto);
                value0.put(proInfo.get(i).getNodeIndex(), p0);
            }

            Map<Integer, Integer> value = new HashMap<Integer, Integer>();
            int p = pIdNumber * 2;
            for (int i = 0; i < gdInfo.size(); i++) {
                Tree dto = new Tree();
                dto.setId(++p);
                dto.setName(gdInfo.get(i).getName());
                dto.setpId(value0.get(gdInfo.get(i).getpId()));
                dto.setPpId(gdInfo.get(i).getpId());
                dto.setNodeIndex(gdInfo.get(i).getNodeIndex());
                dto.setNodeType(2);

                Line gd_line = new Line();
                gd_line.setGdIndex((long) gdInfo.get(i).getNodeIndex());
                List<Line> lines = lineMapper.select(gd_line);
                List<Integer> indexs = new ArrayList<>();
                for (int n = 0; n < lines.size(); n++) {
                    indexs.add(lines.get(n).getLineIndex().intValue());
                }
                list.add(dto);
                value.put(gdInfo.get(i).getNodeIndex(), p);
            }

            Map<Integer, Integer> value1 = new HashMap<Integer, Integer>();
            int p1 = pIdNumber * 3;
            for (int i = 0; i < subInfo.size(); i++) {
                if (value.get(subInfo.get(i).getpId()) != null) {
                    Tree dto = new Tree();
                    dto.setId(++p1);
                    dto.setName(subInfo.get(i).getName());
                    dto.setpId(value.get(subInfo.get(i).getpId()));
                    dto.setPpId(subInfo.get(i).getpId());
                    dto.setNodeIndex(subInfo.get(i).getNodeIndex());
                    dto.setNodeType(3);

                    Line sub_line = new Line();
                    sub_line.setSubIndex((long) subInfo.get(i).getNodeIndex());
                    List<Line> lines = lineMapper.select(sub_line);
                    List<Integer> indexs = new ArrayList<>();
                    for (int n = 0; n < lines.size(); n++) {
                        indexs.add(lines.get(n).getLineIndex().intValue());
                    }
                    list.add(dto);
                    value1.put(subInfo.get(i).getNodeIndex(), p1);
                }
            }


            Map<Integer, Integer> value3 = new HashMap<Integer, Integer>();
            int p3 = pIdNumber * 4;
            for (int i = 0; i < subvInfo.size(); i++) {
                if (value1.get(subvInfo.get(i).getpId()) != null) {
                    List<Tree> lines = lineMapper.getTreeBySubv(Integer.valueOf(subvInfo.get(i).getNodeIndex()).longValue(), null);
                    for (Tree linetmp : lines) {
                        String nameinfo = subvInfo.get(i).getName() + "_" + linetmp.getName();
                        Tree dto = new Tree();
                        dto.setId(++p3);
                        dto.setName(nameinfo);
                        dto.setpId(value1.get(subvInfo.get(i).getpId()));
                        dto.setPpId(subvInfo.get(i).getpId());
                        dto.setNodeIndex(linetmp.getNodeIndex());
                        dto.setNodeType(4);
                        dto.setState(linetmp.getState());
                        dto.setStatus(linetmp.getStatus());
                        dto.setPttype(linetmp.getPttype());

                        List<Integer> indexs = new ArrayList<>();
                        for (int n = 0; n < lines.size(); n++) {
                            indexs.add(lines.get(n).getNodeIndex());
                        }
                        list.add(dto);
                        value3.put(subvInfo.get(i).getNodeIndex(), p3);
                    }
                }
            }
            return list;
        }
    }


    private Object formatObject(Object obj) {
        if (obj == null) {
            return 0;
        } else {
            return obj;
        }
    }

    @Override
    public String getAllWavedataToCsv(String startTime, String endTime, int flag, Integer type) {

        WaveData waveData = new WaveData();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date start;
        Date end;
        try {

            start = simpleDateFormat.parse(startTime);
            end = simpleDateFormat.parse(endTime);

            if (DateUtil.betweenDay(start, end, false) > 31) {
                return "数据量较大确保每次导出时间小于一个月";
            }

        } catch (ParseException e) {
            return "时间格式有误";
        }

        Example example = new Example(EventDetail.class);
        example.createCriteria().andBetween("timeId", start, end).andEqualTo("waveType",1).andEqualTo("fileFlag","1").andIsNotNull("waveName");
        List<EventDetail> eventDetailList = eventDetailMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(eventDetailList)) {
            return "当前时间段暂无暂降事件";
        }

        //读取配置文件
        String tmpPath = appConfig.getTmppath() + File.separator + "exportWaveCsv";
        File fileaa = new File(tmpPath);
        if (!fileaa.exists()) {
            fileaa.mkdirs();
        }

        List<String> srcList = new ArrayList<>();
        for (EventDetail eventDetail : eventDetailList) {
            if (eventDetail != null) {
                //获取PT变比
                Line line = lineService.getLineByEventDetailIndex(eventDetail.getEventDetailIndex());
                waveData.setLineName(line.getName());
                /*********** Modify by xuyang 添加变电站名称---Start **************/
                waveData.setSubName(csvDataMapper.getSubNameById(line.getSubIndex()));
                /***********  Modify by xuyang ---End  **************/
                waveData.setEventValue(PubUtils.floatRound(2, eventDetail.getEventValue() * 100));
                waveData.setPersistTime(PubUtils.floatRound(3, eventDetail.getPersistTime() / 1000));
                waveData.setTrigeTime(AnalyWave.getTimeWave());
                if (Objects.nonNull(line)) {
                    float pt1 = line.getPt1();
                    float pt2 = line.getPt2();
                    float pt = (pt1) / (pt2);
                    waveData.setPt(pt);
                    float ct1 = line.getCt1();
                    float ct2 = line.getCt2();
                    float ct = (ct1) / (ct2);
                    waveData.setCt(ct);
                    //获取接线方式
                    LineDetail lineDetail = new LineDetail();
                    lineDetail.setLineIndex(line.getLineIndex());
                    lineDetail = lineDetailMapper.selectOne(lineDetail);
                    if (null != lineDetail && lineDetail.getPtType() != 0) {
                        //赋值abc三相名称
                        if (lineDetail.getPtType() == 2) {
                            waveData.setOpen(true);
                        }
                    }
                }

                //暂降发生时间
                String time = simpleDateFormat.format(eventDetail.getTimeId()) + "." + PubUtils.getMs(eventDetail.getMs());
                waveData.setTime(time);
                //暂降类型
                if (Integer.parseInt(eventDetail.getFileFlag()) == 1) {
                    //根据暂降事件，返回波形文件名
                    String ip = deviceService.getIPByIndex(line.getDevIndex().toString());
                    if (StringUtils.isBlank(ip)) {
                        return "获取装置ip出错";
                    }
                    String path = appConfig.getWavePath();
                    path = path + File.separator + ip;
                    String waveName = getWaveName(eventDetail, path);
                    String pathTemp = path + File.separator + waveName;
                    File file = new File(pathTemp);
                    // 判断文件是否存在
                    if (file.isFile() && file.exists()) {
                        logger.info(pathTemp + "路径下，文件找到了");
                        //CFG文件路径 pathTemp
                        //获取波形的瞬时值、RMS值数据
                        AnalyWave analyWave = new AnalyWave();
                        AnalyWaveModel.tagDataValue tagDataValue = analyWave.readComtrade(pathTemp, null, flag);
                        //获取瞬时波形值
                        List<List<Float>> shunWave = tagDataValue.getListWaveData();

                        if (type == 2) {
                            //RMS值波形
                            shunWave = analyWave.showValidData(shunWave);
                        }

                        List<String> tmpWaveTitle = tagDataValue.getTmpWaveTitle().stream().map(item->{
                            String tem;
                            if (item.equals("Time")) {
                                tem = "时间(ms)";
                            }else {
                                tem = item;
                            }
                            return tem;
                        }).collect(Collectors.toList());
                        waveData.setTmpWaveTitle(tmpWaveTitle);

                        String titleCal = "顺时波形";
                        if (type == 2) {
                            titleCal = "RMS波形";
                        }

                        String children =waveData.getSubName()+"_"+waveData.getLineName() + "_" + eventDetail.getWaveName() + "_" + eventDetail.getTimeId().getTime() + titleCal + ".csv";
                        String allSrc = tmpPath + File.separator + children;
                        writeCsv(waveData, shunWave, allSrc, children, srcList);


                    } else {
                        logger.error(pathTemp + "路径下，文件找不到..........");
                    }

                }

            }
        }

        //读取配置文件
        String tmpPathZip = appConfig.getTmppath() + File.separator + "exportWaveCsvZip";
        File file = new File(tmpPathZip);
        if (!file.exists()) {
            file.mkdirs();
        }


        zipFiles(srcList, tmpPath, tmpPathZip);
        return "成功";
    }


    private void writeCsv(WaveData waveData, List<List<Float>> shunWave, String allSrc, String fileSrc, List<String> srcList) {
        DecimalFormat decimalFormat = new DecimalFormat("#.00");

        File itemFile = new File(allSrc);
        if(!itemFile.exists()){
            try {
                itemFile.createNewFile();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        // 创建CSV文件对象
        FileWriter writer = null;
        try {
            writer = new FileWriter(allSrc,"utf8");

            // 写入表头

            String header = StringUtils.join(waveData.getTmpWaveTitle(), ",");
            writer.append(header);
            writer.append("\n");

            // 写入数据行
            StringBuilder data = new StringBuilder();
            for (List<Float> item : shunWave) {


                for (int i = 0; i < item.size(); i++) {
                    Float val ;
                    if(i != 0){
                        if(waveData.getTmpWaveTitle().get(i).contains("U")) {
                            val = (item.get(i) * waveData.getPt() / 1000);
                            val = Float.parseFloat(decimalFormat.format(val));
                        }else{
                            val = item.get(i) * waveData.getCt();
                            val = Float.parseFloat(decimalFormat.format(val));
                        }
                    }else {
                        val =item.get(i);
                    }

                    if (i == item.size() - 1) {
                        data.append(val).append("\n");
                    } else {
                        data.append(val).append(",");
                    }
                }
            }
            writer.append(data.toString());
            // 关闭CSV文件
            System.out.println("CSV文件导出成功！");
            srcList.add(fileSrc);
        } catch (Exception e) {
            System.out.println("导出CSV文件失败：" + e.getMessage());
        } finally {
            try {
                assert writer != null;

            } catch (Exception e) {
                e.printStackTrace();
            }
        }


    }

    //根据暂降事件获取波形文件名 CFG为结尾
    private String getWaveName(EventDetail eventDetail, String path) {
        String waveName = eventDetail.getWaveName();
        if (StringUtils.isNotBlank(waveName)) {
            waveName = waveName + ".CFG";
        } else {
            String timeID;
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateString = simpleDateFormat.format(eventDetail.getTimeId());
            String year = dateString.substring(0, 10);
            year = year.replaceAll("-", "");
            String hour = dateString.substring(11);
            hour = hour.replaceAll(":", "");
            DecimalFormat df = new DecimalFormat("000");
            String msStr = df.format(eventDetail.getMs());
            timeID = year + "_" + hour + "_" + msStr;
            int lineID = eventDetail.getLineId().intValue() % 10;
            timeID = lineID + "_" + timeID;
            waveName = timeID + ".CFG";
        }
        return waveName;
    }

    /**
     * 下载数据包
     *
     * @param response
     * @date: 2021/3/25 15:36
     * @return: void
     */
    @Override
    public void downloadDataZip(HttpServletResponse response) {
        //读取配置文件
        String tmpPathZip = appConfig.getTmppath() + File.separator + "exportWaveCsvZip";
        String tmpPath = appConfig.getTmppath() + File.separator + "exportWaveCsv";

        //删除源文件
        File delFile = new File(tmpPath);
        deleteFile(delFile);

        String title = "报告源数据包.zip";
        String filename = System.currentTimeMillis() + "_" + title;
        //设置文件路径
        File filePath = new File(tmpPathZip + File.separator + title);
        if (filePath.exists()) {
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                response.setContentType("application/octet-stream");
                response.setHeader("Content-disposition", "attachment; filename=" + new String(filename.getBytes("utf-8"), "ISO8859-1"));
                byte[] buffer = new byte[4096];
                fis = new FileInputStream(filePath);
                bis = new BufferedInputStream(fis);
                OutputStream os = response.getOutputStream();
                int i = bis.read(buffer);
                while (i != -1) {
                    os.write(buffer, 0, i);
                    i = bis.read(buffer);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                        // 删除临时文件
                        filePath.delete();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }






            }
        }
    }

    public Boolean deleteFile(File file) {
        //判断文件不为null或文件目录存在
        if (file == null || !file.exists()) {
            System.out.println("文件删除失败,请检查文件是否存在以及文件路径是否正确");
            return false;
        }
        //获取目录下子文件
        File[] files = file.listFiles();
        //遍历该目录下的文件对象
        for (File f : files) {
            //判断子目录是否存在子目录,如果是文件则删除
            if (f.isDirectory()) {
                //递归删除目录下的文件
                deleteFile(f);
            } else {
                //文件删除
                f.delete();
                //打印文件名
                System.out.println("文件名：" + f.getName());
            }
        }
        //文件夹删除
        file.delete();
        System.out.println("目录名：" + file.getName());
        return true;
    }

    public void zipFiles(List<String> srcFiles, String srcFile, String tmpPathZip) {
        srcFiles = srcFiles.stream().distinct().collect(Collectors.toList());
        String title = "报告源数据包.zip";
        File zip = new File(tmpPathZip + File.separator + title);
        // 判断压缩后的文件存在不，不存在则创建
        if (!zip.exists()) {
            try {
                zip.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 创建 FileOutputStream 对象
        FileOutputStream fileOutputStream =null;
        // 创建 ZipOutputStream
        ZipOutputStream zipOutputStream =null;
        // 创建 FileInputStream 对象
        BufferedInputStream bis = null;

        FileInputStream inputStream = null;

        try {
            // 实例化 FileOutputStream 对象
            fileOutputStream = new FileOutputStream(zip);
            // 实例化 ZipOutputStream 对象
            zipOutputStream = new ZipOutputStream(fileOutputStream);
            // 创建 ZipEntry 对象
            ZipEntry zipEntry;
            // 遍历源文件数组
            for (String file : srcFiles) {
                // 将源文件数组中的当前文件读入 FileInputStream 流中
                String fileName = file;
                fileName = URLDecoder.decode(fileName, "UTF-8");
                //获取文件输入流  localFileDir是服务端存储文件的路径
                File files = new File(srcFile + File.separator + fileName);
                inputStream = new FileInputStream(files);
                // 文件后缀名称
                // 实例化 ZipEntry 对象，源文件数组中的当前文件
                zipEntry = new ZipEntry(fileName);
                zipOutputStream.putNextEntry(zipEntry);
                // 该变量记录每次真正读的字节个数
                int len;
                // 定义每次读取的字节数组
                byte[] buffer = new byte[4096];
                while ((len = inputStream.read(buffer)) > 0) {
                    zipOutputStream.write(buffer, 0, len);
                }

            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            try {
                zipOutputStream.closeEntry();
                zipOutputStream.close();
                fileOutputStream.close();
                if (bis != null) {
                    bis.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
                System.gc();//否则源文件删除时可能有问题
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


}
