package cn.cecep.talroad.service.impl.analysis;

import cn.cecep.talroad.common.core.utils.DateUtils;
import cn.cecep.talroad.common.core.utils.StringUtils;
import cn.cecep.talroad.domain.analysis.SRaRealTimeAnalysisCo;
import cn.cecep.talroad.mapper.analysis.SRaRealTimeAnalysisCoMapper;
import cn.cecep.talroad.service.analysis.ISRaRealTimeAnalysisCoService;
import cn.cecep.talroad.util.ExportWordUtil;
import cn.cecep.talroad.vo.EChartsVO;
import cn.cecep.talroad.vo.analysis.CoDeviceDiffuseStatusFactoryVO;
import cn.cecep.talroad.vo.analysis.CoDeviceTypeCountVO;
import cn.cecep.talroad.vo.analysis.CoDeviceTypeDiffuseStatusVO;
import cn.cecep.talroad.vo.query.analysis.SRaRealTimeAnalysisCoQuery;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import freemarker.template.TemplateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
 * co放散分析Service业务层处理
 *
 * @author szhpt
 * @date 2023-03-24*/
@Service
public class SRaRealTimeAnalysisCoServiceImpl extends ServiceImpl<SRaRealTimeAnalysisCoMapper, SRaRealTimeAnalysisCo> implements ISRaRealTimeAnalysisCoService
{
    @Autowired
    private SRaRealTimeAnalysisCoMapper sRaRealTimeAnalysisCoMapper;

    /**
     * 查询co放散分析列表
     *
     * @param sRaRealTimeAnalysisCo co放散分析
     * @return co放散分析
     */
    @Override
    public List<SRaRealTimeAnalysisCo> selectSRaRealTimeAnalysisCoList(SRaRealTimeAnalysisCoQuery sRaRealTimeAnalysisCo)
    {
        Page<SRaRealTimeAnalysisCo> page=new Page<>(1,999999);
        List<SRaRealTimeAnalysisCo> list =sRaRealTimeAnalysisCoMapper.selectSRaRealTimeAnalysisCoList(page,sRaRealTimeAnalysisCo);
        List<String> stringList=new ArrayList<>();
        list.forEach(item->{
            stringList.add(item.getDeviceId());
        });
        List<SRaRealTimeAnalysisCo> listItem=sRaRealTimeAnalysisCoMapper.selectSRaRealTimeAnalysisCoListById(sRaRealTimeAnalysisCo,stringList);
        Map<String, List<SRaRealTimeAnalysisCo>> stringListMap = listItem.stream().collect(Collectors.groupingBy( SRaRealTimeAnalysisCo::getDeviceId));
        list.forEach(item->{
            if(stringListMap.containsKey(item.getDeviceId())){
                List<SRaRealTimeAnalysisCo> coList = stringListMap.get(item.getDeviceId());
                Map<String, String> map = runStatusConver(coList);
                item.setDiffuse(map.get("diffuse"));
                item.setRemark(map.get("remark"));

                BigDecimal coalEmissions = coList.stream().map(SRaRealTimeAnalysisCo::getCoalEmissions).filter(Objects::nonNull).reduce(BigDecimal::add).orElse(null);
                item.setCoalEmissions(coalEmissions);
            }
        });
        return list;
    }

    @Override
    public List<Map<String, Object>> pullWorkingProcedureOptions(String industryCategoryCode) {
        List<Map<String, Object>> map =new ArrayList<>();
        if(industryCategoryCode.equals("GT")){
            List<String> numbers = Arrays.asList("高炉煤气放散火炬-GLMQ", "高炉煤气柜-GLMQG", "转炉-ZL","煤气管网-MQGW");
            numbers.forEach(item->{
                Map<String, Object> objectMap=new HashMap<>();
                objectMap.put("label",item.split("-")[0]);
                objectMap.put("value",item.split("-")[1]);
                map.add(objectMap);
            });
        }
        if(industryCategoryCode.equals("JH")){
            List<String> numbers = Arrays.asList("煤气管网-MQGW");
            numbers.forEach(item->{
                Map<String, Object> objectMap=new HashMap<>();
                objectMap.put("label",item.split("-")[0]);
                objectMap.put("value",item.split("-")[1]);
                map.add(objectMap);
            });
        }
        return map;
    }

    @Override
    public IPage<SRaRealTimeAnalysisCo> selectSRaRealTimeAnalysisCoListPage(SRaRealTimeAnalysisCoQuery sRaRealTimeAnalysisCo) {
        Page<SRaRealTimeAnalysisCo> iPage=new  Page<SRaRealTimeAnalysisCo>(sRaRealTimeAnalysisCo.getPageNum(),sRaRealTimeAnalysisCo.getPageSize());
        List<SRaRealTimeAnalysisCo> list=sRaRealTimeAnalysisCoMapper.selectSRaRealTimeAnalysisCoListPage(iPage,sRaRealTimeAnalysisCo);
        List<String> stringList=new ArrayList<>();
        list.forEach(item->{
            stringList.add(item.getDeviceId());
        });
        List<SRaRealTimeAnalysisCo> listItem=sRaRealTimeAnalysisCoMapper.selectSRaRealTimeAnalysisCoListById(sRaRealTimeAnalysisCo,stringList);
        Map<String, List<SRaRealTimeAnalysisCo>> stringListMap = listItem.stream().collect(Collectors.groupingBy( SRaRealTimeAnalysisCo::getDeviceId));
        list.forEach(item->{
            if(stringListMap.containsKey(item.getDeviceId())){
                List<SRaRealTimeAnalysisCo> coList = stringListMap.get(item.getDeviceId());
                Map<String, String> map = runStatusConver(coList);
                item.setDiffuse(map.get("diffuse"));
                item.setRemark(map.get("remark"));

                BigDecimal coalEmissions = coList.stream().map(SRaRealTimeAnalysisCo::getCoalEmissions).filter(Objects::nonNull).reduce(BigDecimal::add).orElse(null);
                item.setCoalEmissions(coalEmissions);
            }
        });
        iPage.setRecords(list);
        return iPage;
    }
    public Map<String,String> runStatusConver(List<SRaRealTimeAnalysisCo> list){
        Map<String,String> map=new HashMap<>();
        String finalValue="";
        String start="";
        String end="";
        String goingsOn="";
        TreeSet<String> chilePollutant = new TreeSet<>();
        TreeSet<String> goingsOnArr = new TreeSet<>();
        if(CollectionUtil.isNotEmpty(list)){
            if(StringUtils.isNotEmpty(list.get(0).getDiffuseStatus())){
                finalValue= list.get(0).getDiffuseStatus();
                start=DateUtil.format(list.get(0).getDiffuseEndTime(),DatePattern.NORM_DATETIME_MINUTE_PATTERN);
                if(StringUtils.isNotEmpty(list.get(0).getRemark())){
                    goingsOn=list.get(0).getRemark();
                }
            }
        }
        for (SRaRealTimeAnalysisCo runStatus : list) {
            if(StringUtils.isNotEmpty(runStatus.getDiffuseStatus())){
                if(finalValue.equals(runStatus.getDiffuseStatus())){
                    end=DateUtil.format(runStatus.getDiffuseEndTime(),DatePattern.NORM_DATETIME_MINUTE_PATTERN);
                }else {
                    chilePollutant.add(String.format("%s至%s%s",start,end,operationStatus(finalValue)));
                    if(StringUtils.isNotEmpty(goingsOn)) {
                        goingsOnArr.add(goingsOn);
                    }
                    start=DateUtil.format(runStatus.getDiffuseEndTime(),DatePattern.NORM_DATETIME_MINUTE_PATTERN);
                    end=DateUtil.format(runStatus.getDiffuseEndTime(),DatePattern.NORM_DATETIME_MINUTE_PATTERN);
                    finalValue=runStatus.getDiffuseStatus();
                    if(StringUtils.isNotEmpty(runStatus.getRemark())){
                        goingsOn=runStatus.getRemark();
                    }
                }
            }
        }
        if(StringUtils.isNotEmpty(finalValue)) {
            chilePollutant.add(String.format("%s至%s%s",start,end,operationStatus(finalValue)));
        }
        if(StringUtils.isNotEmpty(goingsOn)) {
            goingsOnArr.add(goingsOn);
        }
        map.put("diffuse",String.join("，", chilePollutant));
        map.put("remark",String.join("，", goingsOnArr));
        return map;
    }
    public String operationStatus(String status){
        String str="";
        if(status.equals("1")){
            str="正常放散";
        }
        if(status.equals("2")){
            str="异常放散";
        }
        if(status.equals("3")){
            str="未放散";
        }
        if(status.equals("4")){
            str="离线";
        }
        if(status.equals("5")){
            str="异常";
        }
        return  str;
    };
    @Override
    public EChartsVO resultCurve(String deviceId, String monitoringStartTime, String monitoringEndTime) {
        QueryWrapper<SRaRealTimeAnalysisCo> wrapper=new QueryWrapper<SRaRealTimeAnalysisCo>();
        wrapper.eq(StringUtils.isNotEmpty(deviceId), "device_id", deviceId);
        wrapper.ge("analyse_time", DateUtil.parse(monitoringStartTime,"yyyy-MM-dd HH:mm:ss"));
        wrapper.le("analyse_time", DateUtil.parse(monitoringEndTime,"yyyy-MM-dd HH:mm:ss"));
        wrapper.orderByAsc("diffuse_end_time");
        List<SRaRealTimeAnalysisCo> sRaRealTimeAnalysisRuns = sRaRealTimeAnalysisCoMapper.selectList(wrapper);
        Map<String, String> timeStatusMap = sRaRealTimeAnalysisRuns.stream().filter(o->o.getDiffuseStatus()!=null).collect(Collectors.toMap(o ->  DateUtil.format(o.getDiffuseEndTime(),DatePattern.NORM_DATETIME_MINUTE_FORMATTER), o ->  o.getDiffuseStatus(), (o1, o2) -> o1));
        // x轴数据
        List<String> xdata = DateUtils.getRangeTimes("M", monitoringStartTime, monitoringEndTime);

        EChartsVO.SeriesObj ser1 = new EChartsVO.SeriesObj();
        ser1.setName("正常放散");
        ser1.setProp("1");
        ser1.setValues(new ArrayList<>());

        EChartsVO.SeriesObj ser2 = new EChartsVO.SeriesObj();
        ser2.setName("异常放散");
        ser2.setProp("2");
        ser2.setValues(new ArrayList<>());

        EChartsVO.SeriesObj ser3 = new EChartsVO.SeriesObj();
        ser3.setName("未放散");
        ser3.setProp("3");
        ser3.setValues(new ArrayList<>());

        EChartsVO.SeriesObj ser4 = new EChartsVO.SeriesObj();
        ser4.setName("离线");
        ser4.setProp("4");
        ser4.setValues(new ArrayList<>());

        EChartsVO.SeriesObj ser5 = new EChartsVO.SeriesObj();
        ser5.setName("异常");
        ser5.setProp("5");
        ser5.setValues(new ArrayList<>());

        EChartsVO chartsVO = new EChartsVO();
        chartsVO.setXData(xdata);
        chartsVO.setSeries(Arrays.asList(ser1, ser2, ser3, ser4,ser5));

        /*
            填充系列值
         */
        // 遍历x轴，保证系列值与x轴刻度一一对应
        for (String time : xdata) {
            String status = timeStatusMap.get(time);

            for (EChartsVO.SeriesObj ser : chartsVO.getSeries()) {
                // 若系列的prop属性与状态码相等，则设置系列值为状态码，否则填充null
                if (ser.getProp().equals(status)) {
                    ser.getValues().add(status);
                } else {
                    ser.getValues().add(null);
                }
            }
        }
        return chartsVO;
    }

    @Override
    public String analysisCurveEndTime(String deviceId, String monitoringStartTime, String monitoringEndTime) {
        String sRaRealTimeAnalysisRuns = sRaRealTimeAnalysisCoMapper.analysisCurveEndTime(deviceId,DateUtil.parse(monitoringStartTime,"yyyy-MM-dd HH:mm:ss"), DateUtil.parse(monitoringEndTime,"yyyy-MM-dd HH:mm:ss"));
        return sRaRealTimeAnalysisRuns;
    }

    /**
     * 导出CO数据为word文档
     * @param sRaRealTimeAnalysisCo 查询条件
     * @param response 响应对象
     */
    @Override
    public void exportCoDataToWord(SRaRealTimeAnalysisCoQuery sRaRealTimeAnalysisCo, HttpServletResponse response) throws IOException, TemplateException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        String[] paramList = new String[]{"GLMQ","GLMQG","ZL","MQGW"};
        //获取设备总数量
        CoDeviceTypeCountVO coDeviceTypeCountVO = sRaRealTimeAnalysisCoMapper.selectDeviceTypeCount(sRaRealTimeAnalysisCo);
        //获取设备状态数量
        List<CoDeviceTypeDiffuseStatusVO> coDeviceTypeDiffuseStatusVOS = sRaRealTimeAnalysisCoMapper.selectDeviceTypeDiffuseStatusCount(sRaRealTimeAnalysisCo);
        //获取状态企业数量
        List<CoDeviceDiffuseStatusFactoryVO> coDeviceDiffuseStatusFactoryVOS = sRaRealTimeAnalysisCoMapper.selectDeviceDiffuseStatusFactoryList(sRaRealTimeAnalysisCo);
        Map map = new HashMap();
        Class<? extends CoDeviceTypeCountVO> aClass = coDeviceTypeCountVO.getClass();
        //插入时间
        map.put("dataTime",sRaRealTimeAnalysisCo.getAnalyseStartTime()+"-"+sRaRealTimeAnalysisCo.getAnalyseEndTime());
        for (String param : paramList) {
            //设备总数量添加
            Method method = aClass.getMethod("get" + param + "Count");
            map.put(param+"Count",method.invoke(coDeviceTypeCountVO));
            //初始化0给每个参数
            map.put(param+"NormalCount",0);
            map.put(param+"ExceptionCount",0);
            map.put(param+"UndoCount",0);
            map.put(param+"NoDataCount",0);
            map.put(param+"ExceptionDataCount",0);
            Map<String,Integer> deviceIndexOrderMap = new HashMap<>();
            //设备状态数量添加,五种状态，每个设备只能统计一次 优先级：异常放散>正常放散>异常>未放散>离线
            for (CoDeviceTypeDiffuseStatusVO coDeviceTypeDiffuseStatusVO : coDeviceTypeDiffuseStatusVOS) {
                if(!coDeviceTypeDiffuseStatusVO.getDeviceType().equalsIgnoreCase(param)){
                    continue;
                }
                int deviceIndexOrder = -1;
                if(coDeviceTypeDiffuseStatusVO.getDiffuseStatus().compareTo("1") == 0){
                    deviceIndexOrder = 1;
                } else if (coDeviceTypeDiffuseStatusVO.getDiffuseStatus().compareTo("2") == 0) {
                    deviceIndexOrder = 0;
                }else if (coDeviceTypeDiffuseStatusVO.getDiffuseStatus().compareTo("3") == 0) {
                    deviceIndexOrder = 3;
                }else if (coDeviceTypeDiffuseStatusVO.getDiffuseStatus().compareTo("4") == 0) {
                    deviceIndexOrder = 4;
                }else if (coDeviceTypeDiffuseStatusVO.getDiffuseStatus().compareTo("5") == 0) {
                    deviceIndexOrder = 2;
                }
                //该设备首次出现，直接装入优先级容器
                if(!deviceIndexOrderMap.containsKey(coDeviceTypeDiffuseStatusVO.getDeviceId())){
                    deviceIndexOrderMap.put(coDeviceTypeDiffuseStatusVO.getDeviceId(),deviceIndexOrder);
                }
                //检查优先级是否更高,更高则替换
                if (deviceIndexOrderMap.get(coDeviceTypeDiffuseStatusVO.getDeviceId()).compareTo(deviceIndexOrder) >0) {
                    deviceIndexOrderMap.put(coDeviceTypeDiffuseStatusVO.getDeviceId(),deviceIndexOrder);
                }
            }
            //进行统计
            for (Map.Entry<String, Integer> stringIntegerEntry : deviceIndexOrderMap.entrySet()) {
                switch (stringIntegerEntry.getValue()){
                    case 0:
                        map.put(param+"ExceptionCount",((Integer)map.get(param+"ExceptionCount"))+1);
                        break;
                    case 1:
                        map.put(param+"NormalCount",((Integer)map.get(param+"NormalCount"))+1);
                        break;
                    case 2:
                        map.put(param+"ExceptionDataCount",((Integer)map.get(param+"ExceptionDataCount"))+1);
                        break;
                    case 3:
                        map.put(param+"UndoCount",((Integer)map.get(param+"UndoCount"))+1);
                        break;
                    case 4:
                        map.put(param+"NoDataCount",((Integer)map.get(param+"NoDataCount"))+1);
                }
            }
            //四个列表中，企业名称只展示一次,优先级：异常放散>正常放散>异常>未放散>离线
            //2023.7.5姚婧提出企业不按优先级划分只展示一次了
            StringBuilder exceptionFactoryList = new StringBuilder(),
                    normalFactoryList = new StringBuilder(),
                    noDataFactoryList = new StringBuilder(),
                    exceptionDataFactoryList = new StringBuilder();
            //Map<String,Integer> factoryOrderMap = new HashMap<>();
            for (CoDeviceDiffuseStatusFactoryVO coDeviceDiffuseStatusFactoryVO : coDeviceDiffuseStatusFactoryVOS) {
                if(!coDeviceDiffuseStatusFactoryVO.getDeviceType().equalsIgnoreCase(param)){
                    continue;
                }
                //int index = -1;
                if(coDeviceDiffuseStatusFactoryVO.getDiffuseStatus().compareTo("1") == 0){
                    normalFactoryList.append(","+coDeviceDiffuseStatusFactoryVO.getFactoryName());
                    //index = 1;
                }else if(coDeviceDiffuseStatusFactoryVO.getDiffuseStatus().compareTo("2") == 0){
                    exceptionFactoryList.append(","+coDeviceDiffuseStatusFactoryVO.getFactoryName());
                    //index = 0;
                }else if(coDeviceDiffuseStatusFactoryVO.getDiffuseStatus().compareTo("4") == 0){
                    exceptionDataFactoryList.append(","+coDeviceDiffuseStatusFactoryVO.getFactoryName());
                    //index = 3;
                }else if(coDeviceDiffuseStatusFactoryVO.getDiffuseStatus().compareTo("5") == 0){
                    noDataFactoryList.append(","+coDeviceDiffuseStatusFactoryVO.getFactoryName());
                    //index = 2;
                }
                //该企业首次出现，直接装入优先级容器
//                if(!factoryOrderMap.containsKey(coDeviceDiffuseStatusFactoryVO.getFactoryName())){
//                    factoryOrderMap.put(coDeviceDiffuseStatusFactoryVO.getFactoryName(),index);
//                }
//                //检查优先级是否更高,更高则替换
//                if (index >= 0 && factoryOrderMap.get(coDeviceDiffuseStatusFactoryVO.getFactoryName()).compareTo(index) >0) {
//                    factoryOrderMap.put(coDeviceDiffuseStatusFactoryVO.getFactoryName(),index);
//                }
            }
            //状态企业数量添加
//            for (Map.Entry<String, Integer> stringIntegerEntry : factoryOrderMap.entrySet()) {
//                switch (stringIntegerEntry.getValue()){
//                    case 0:
//                        exceptionFactoryList.append(","+stringIntegerEntry.getKey());
//                        break;
//                    case 1:
//                        normalFactoryList.append(","+stringIntegerEntry.getKey());
//                        break;
//                    case 2:
//                        noDataFactoryList.append(","+stringIntegerEntry.getKey());
//                        break;
//                    case 3:
//                        exceptionDataFactoryList.append(","+stringIntegerEntry.getKey());
//                }
//            }
            map.put(param+"ExceptionFactoryList",exceptionFactoryList.length()>0?"存在异常放散的企业为："+exceptionFactoryList.substring(1).toString()+"。\n":"");
            map.put(param+"NormalFactoryList",normalFactoryList.length()>0?"存在正常放散的企业为："+normalFactoryList.substring(1).toString()+"。\n":"");
            map.put(param+"NoDataFactoryList",noDataFactoryList.length()>0?"存在数据缺失情况的企业为："+noDataFactoryList.substring(1).toString()+"。\n":"");
            map.put(param+"ExceptionDataFactoryList",exceptionDataFactoryList.length()>0?"放散口温度缺失的企业为："+exceptionDataFactoryList.substring(1).toString()+"。\n":"");
        }
        //导出到word文档
        ExportWordUtil.exportToWord(map,response, "wordReport/COReport.ftl", "wordReport/COOutFile.docx","CO放散分析报告.docx");
    }

    @Override
    public EChartsVO coalEmissionsChart(String deviceId, String monitoringStartTime, String monitoringEndTime) {
        List<SRaRealTimeAnalysisCo> coList = sRaRealTimeAnalysisCoMapper.selectList(
                new QueryWrapper<SRaRealTimeAnalysisCo>()
                        .eq("device_id", deviceId)
                        .ge("analyse_time", DateUtil.parse(monitoringStartTime,"yyyy-MM-dd HH:mm:ss"))
                        .le("analyse_time", DateUtil.parse(monitoringEndTime,"yyyy-MM-dd HH:mm:ss"))
                        .isNotNull("diffuse_end_time")
                        .isNotNull("coal_emissions")
        );
        Map<String, BigDecimal> timeStatusMap = coList.stream().collect(Collectors.toMap(
                o -> DateUtil.format(o.getDiffuseEndTime(), DatePattern.NORM_DATETIME_MINUTE_FORMATTER),
                SRaRealTimeAnalysisCo::getCoalEmissions,
                (o1, o2) -> o1));

        // x轴数据
        List<String> xdata = DateUtils.getRangeTimes("M", monitoringStartTime, monitoringEndTime);

        /*
            参考echars 阶梯瀑布图demo
            https://echarts.apache.org/examples/zh/editor.html?c=bar-waterfall2

            income（增加量）   900, 345, 393,  '-',  '-',  135,  178,  286,  '-',  '-',  '-'
            expense（减少量）  '-', '-', '-',  108,  154,  '-',  '-',  '-',  119,  361,  203

            result是记录每次增加或减少的结果，初始值为0
            result            900  1245 1638  1530  1376  1511  1689  1975  1856  1495  1292

            placeholder：
                若income不为null，则placeholder = result - income；
                若expense不为null，则placeholder = result；
                若income和expense都是null，则placeholder = null；
            placeholder       0,   900, 1245, 1530, 1376, 1376, 1511, 1689, 1856, 1495, 1292
         */
        List<BigDecimal> placeholderValues = new ArrayList<>(); // 根据增加或减少的系列值进行叠加
        List<BigDecimal> incomeValues = new ArrayList<>(); // 增加的系列值
        List<BigDecimal> expensesValues = new ArrayList<>(); // 减少的系列值

        BigDecimal result = BigDecimal.ZERO; // 记录每次增加或减少的结果，初始值为0

        // 遍历x轴，保证系列值与x轴一一对应
        for (String time : xdata) {
            BigDecimal income = null;
            BigDecimal expense = null;
            BigDecimal placeholder = null;

            BigDecimal value = timeStatusMap.get(time);

            if (value != null) {
                result = result.add(value);

                if (value.compareTo(BigDecimal.ZERO) >= 0) {
                    income = value;
                    placeholder = result.subtract(income);
                } else {
                    expense = value.abs();
                    placeholder = result;
                }
            }
            incomeValues.add(income);
            expensesValues.add(expense);
            placeholderValues.add(placeholder);
        }
        EChartsVO.SeriesObj ser1 = new EChartsVO.SeriesObj();
        ser1.setName("Placeholder");
        ser1.setValues(placeholderValues.stream().map(o -> o == null ? null : o.stripTrailingZeros().toPlainString()).collect(Collectors.toList()));

        EChartsVO.SeriesObj ser2 = new EChartsVO.SeriesObj();
        ser2.setName("增加");
        ser2.setValues(incomeValues.stream().map(o -> o == null ? null : o.stripTrailingZeros().toPlainString()).collect(Collectors.toList()));

        EChartsVO.SeriesObj ser3 = new EChartsVO.SeriesObj();
        ser3.setName("减少");
        ser3.setValues(expensesValues.stream().map(o -> o == null ? null : o.stripTrailingZeros().toPlainString()).collect(Collectors.toList()));

        EChartsVO chartsVO = new EChartsVO();
        chartsVO.setXData(xdata);
        chartsVO.setSeries(Arrays.asList(ser1, ser2, ser3));
        return chartsVO;
    }
}
