package com.reyun.saas.report.data.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.reyun.saas.common.restResult.RestResult;
import com.reyun.saas.common.restResult.ResultGenerator;
import com.reyun.saas.mob.user.dao.AppMapper;
import com.reyun.saas.mob.user.dao.ChannelMapper;
import com.reyun.saas.mob.user.dao.UserMapper;
import com.reyun.saas.mob.user.dao.ViewColumnMapper;
import com.reyun.saas.mob.user.domain.App;
import com.reyun.saas.mob.user.domain.Channel;
import com.reyun.saas.mob.user.domain.User;
import com.reyun.saas.mob.user.domain.ViewColumn;
import com.reyun.saas.mob.user.service.AuthService;
import com.reyun.saas.mob.user.service.ChannelService;
import com.reyun.saas.report.data.dao.DataInfoDayMapper;
import com.reyun.saas.report.data.dao.DataInfoHourMapper;
import com.reyun.saas.report.data.service.DataService;
import com.reyun.saas.report.data.service.DropDownService;
import com.reyun.saas.report.util.ReportParamsUril;
import com.reyun.saas.report.vo.AppkeyAndCids;
import com.reyun.saas.report.vo.ChartVo;
import com.reyun.saas.report.vo.ListVo;
import com.reyun.saas.report.vo.ReportParamsVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @desc
 * @date
 */
@Service
@Slf4j
public class DataServiceImpl implements DataService {
    private static final String left = "left";
    private static final String right = "right";
    private static final String left_relative = "left_relative";
    private static final String right_relative = "right_relative";
    private static final String left_status = "left_status";//0|-，1|持平，2|上升，3|下降
    private static final String right_status = "right_status";
    private static final List<String>  keys = Arrays.asList("00", "01", "02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23");
    private static final DecimalFormat df = new DecimalFormat("#0.00");
    @Autowired
    private DataInfoDayMapper dataInfoDayMapper;
    @Autowired
    private DataInfoHourMapper dataInfoHourMapper;
    @Resource
    private ChannelMapper channelMapper;
    @Resource
    private ViewColumnMapper viewColumnMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private AppMapper appMapper;
    @Autowired
    private AuthService authServiceImpl;
    @Autowired
    private ChannelService channelServiceImpl;
    @Resource
    private DropDownService dropDownServiceImpl;
    /**
     * 环比算法
     * 1.对比的是上一个时段的数据，例如今日的环比为昨日，近7日的环比为近7日外的近7日；
     * 2.环比计算公式：(本时段数据-上时段数据)/上时段数据，例如，昨日数据=3，今日数据=7，则(7-3)/3=133%,环比上涨133%；
     * 3.当上时段数据和本时段数据相等，此时显示环比为【持平】;
     * 4.当上时段数据或本时段数据其中有一方数据为0时，显示环比为【-】；
     * 5.当对比时段超出仅30日时，显示环比为【-】
     * 其他说明
     * 1.切换系统为【iOS】时，所有有关【潜在风险】功能隐藏，包括顶部最右侧的【潜在风险】（隐藏后【异常】居中）、下面各个图标内的【潜在风险XXX】图例；
     * 2.日期控件最多仅能选择近30天数据，其他日期置灰不可选；
     * 3.日期控件快捷键包括【今日】【昨日】【7日】【30日】，默认今日
     * 4.当选择【今日】或【昨日】时，显示小时表，其余日期展示日期表；
     *
     */
    @Override
    public RestResult relative(ReportParamsVO reportParamsVO) {
        defaultAppkeys(reportParamsVO);
        //日期校验&计算环比起始结束日期
        String startDateStr = reportParamsVO.getStartDate();
        String endDateStr = reportParamsVO.getEndDate();
        Date startDate = DateUtil.parse(startDateStr, DatePattern.NORM_DATE_PATTERN).toJdkDate();
        Date endDate = DateUtil.parse(endDateStr, DatePattern.NORM_DATE_PATTERN).toJdkDate();
        if(DateUtil.compare(startDate,endDate)>0){
            return ResultGenerator.genFailResult("结束日期不能早于开始日期");
        }
        String  endDateRelative = DateUtil.offsetDay(startDate, -1).toString(DatePattern.NORM_DATE_PATTERN);
        String startDateRelative = DateUtil.offsetDay(DateUtil.parse(endDateRelative, DatePattern.NORM_DATE_PATTERN).toJdkDate(), reportParamsVO.getBetweenDay() *-1).toString(DatePattern.NORM_DATE_PATTERN);
        ReportParamsVO reportParamsVORelative = new ReportParamsVO();
        BeanUtils.copyProperties(reportParamsVO,reportParamsVORelative);
        reportParamsVORelative.setStartDate(startDateRelative);
        reportParamsVORelative.setEndDate(endDateRelative);
        reportParamsVORelative = ReportParamsUril.handDate(reportParamsVORelative);
        //环比报表
        Map<String, Object> resultData = new HashMap<>();
     //   新增
            Map<String, Object> resultData_new_user = new HashMap<>();

            Map<String, String> params = new HashMap<>();
            params.put("device_status","1");
            int newUserNum = dataInfoDayMapper.relative(reportParamsVO,params);
            resultData_new_user.put(left,newUserNum);
            if(newUserNum==0){
                resultData_new_user.put(left_relative,"-");
                resultData_new_user.put(left_status,0);
            }else if(reportParamsVO.getBetweenDay()>30L){
                resultData_new_user.put(left_relative,"-");
                resultData_new_user.put(left_status,0);
            }else{
                int newUserNumRelative = dataInfoDayMapper.relative(reportParamsVORelative,params);
                if(newUserNumRelative==0){
                    resultData_new_user.put(left_relative,"-");
                    resultData_new_user.put(left_status,0);
                }else if(newUserNumRelative==newUserNum){
                    resultData_new_user.put(left_relative,"持平");
                    resultData_new_user.put(left_status,1);
                }else{
                    double v = (newUserNum - newUserNumRelative)* 100.0d / newUserNumRelative;
                    String format = df.format(v);
                    resultData_new_user.put(left_relative,format+"%");
                    if(v>0){
                        resultData_new_user.put(left_status,2);
                    }else{
                        resultData_new_user.put(left_status,3);
                    }
                }
            }
//新增异常
            params.put("quantity","2");
            int newUserNumExce = dataInfoDayMapper.relative(reportParamsVO,params);
            resultData_new_user.put(right,newUserNumExce);
            if(newUserNumExce==0){
                resultData_new_user.put(right_relative,"-");
                resultData_new_user.put(right_status,0);
            }else if(reportParamsVO.getBetweenDay()>30L){
                resultData_new_user.put(right_relative,"-");
                resultData_new_user.put(right_status,0);
            }else{
                int newUserNumExceRelative = dataInfoDayMapper.relative(reportParamsVORelative,params);
                if(newUserNumExceRelative==0){
                    resultData_new_user.put(right_relative,"-");
                    resultData_new_user.put(right_status,0);
                }else if(newUserNumExceRelative==newUserNumExce){
                    resultData_new_user.put(right_relative,"持平");
                    resultData_new_user.put(right_status,1);
                }else{
                    double b = (newUserNumExce - newUserNumExceRelative)* 100.0d / newUserNumExceRelative;
                    resultData_new_user.put(right_relative,df.format(b)+"%");
                    if(b>0){
                        resultData_new_user.put(right_status,2);
                    }else{
                        resultData_new_user.put(right_status,3);
                    }
                }
            }
            resultData.put("new_user_relative",resultData_new_user);
    // dau

            Map<String, Object> resultData_dau = new HashMap<>();
            params = new HashMap<>();
            int dauNum = dataInfoDayMapper.relativeDau(reportParamsVO,params);
            resultData_dau.put(left,dauNum);
            if(dauNum==0){
                resultData_dau.put(left_relative,"-");
                resultData_dau.put(left_status,0);
            }else if(reportParamsVO.getBetweenDay()>30L){
                resultData_dau.put(left_relative,"-");
                resultData_dau.put(left_status,0);
            }else{
                int dauNumRelative = dataInfoDayMapper.relativeDau(reportParamsVORelative,params);
                if(dauNumRelative==0){
                    resultData_dau.put(left_relative,"-");
                    resultData_dau.put(left_status,0);
                }else if(dauNumRelative==dauNum){
                    resultData_dau.put(left_relative,"持平");
                    resultData_dau.put(left_status,1);
                }else{
                    double v = (dauNum - dauNumRelative)* 100.0d / dauNumRelative;
                    String format = df.format(v);
                    resultData_dau.put(left_relative,format+"%");
                    if(v>0){
                        resultData_dau.put(left_status,2);
                    }else{
                        resultData_dau.put(left_status,3);
                    }
                }
            }
//dau异常
            params.put("quantity","2");
            int dauNumExce = dataInfoDayMapper.relativeDau(reportParamsVO,params);
            resultData_dau.put(right,dauNumExce);
            if(dauNumExce==0){
                resultData_dau.put(right_relative,"-");
                resultData_dau.put(right_status,0);
            }else if(reportParamsVO.getBetweenDay()>30L){
                resultData_dau.put(right_relative,"-");
                resultData_dau.put(right_status,0);
            }else{
                int dauNumExceRelative = dataInfoDayMapper.relativeDau(reportParamsVORelative,params);
                if(dauNumExceRelative==0){
                    resultData_dau.put(right_relative,"-");
                    resultData_dau.put(right_status,0);
                }else if(dauNumExceRelative==dauNumExce){
                    resultData_dau.put(right_relative,"持平");
                    resultData_dau.put(right_status,1);
                }else{
                    double b = (dauNumExce - dauNumExceRelative)* 100.0d / dauNumExceRelative;
                    resultData_dau.put(right_relative,df.format(b)+"%");
                    if(b>0){
                        resultData_dau.put(right_status,2);
                    }else{
                        resultData_dau.put(right_status,3);
                    }
                }
            }
            resultData.put("dau_relative",resultData_dau);
    // 更新

            Map<String, Object> resultData_update = new HashMap<>();
            params = new HashMap<>();
            params.put("appIsUpdate","1");
            int updateNum = dataInfoDayMapper.relative(reportParamsVO,params);
            resultData_update.put(left,updateNum);
            if(updateNum==0){
                resultData_update.put(left_relative,"-");
                resultData_update.put(left_status,0);
            }else if(reportParamsVO.getBetweenDay()>30L){
                resultData_update.put(left_relative,"-");
                resultData_update.put(left_status,0);
            }else{
                int updateNumRelative = dataInfoDayMapper.relative(reportParamsVORelative,params);
                if(updateNumRelative==0){
                    resultData_update.put(left_relative,"-");
                    resultData_update.put(left_status,0);
                }else if(updateNumRelative==updateNum){
                    resultData_update.put(left_relative,"持平");
                    resultData_update.put(left_status,1);
                }else{
                    double v = (updateNum - updateNumRelative)* 100.0d / updateNumRelative;
                    String format = df.format(v);
                    resultData_update.put(left_relative,format+"%");
                    if(v>0){
                        resultData_update.put(left_status,2);
                    }else{
                        resultData_update.put(left_status,3);
                    }
                }
            }
        //异常更新
            params.put("quantity","2");
            int updateNumExce = dataInfoDayMapper.relative(reportParamsVO,params);
            resultData_update.put(right,updateNumExce);
            if(updateNumExce==0){
                resultData_update.put(right_relative,"-");
                resultData_update.put(right_status,0);
            }else if(reportParamsVO.getBetweenDay()>30L){
                resultData_update.put(right_relative,"-");
                resultData_update.put(right_status,0);
            }else{
                int updateNumExceRelative = dataInfoDayMapper.relative(reportParamsVORelative,params);
                if(updateNumExceRelative==0){
                    resultData_update.put(right_relative,"-");
                    resultData_update.put(right_status,0);
                }else if(updateNumExceRelative==updateNumExce){
                    resultData_update.put(right_relative,"持平");
                    resultData_update.put(right_status,1);
                }else{
                    double b = (updateNumExce - updateNumExceRelative)* 100.0d / updateNumExceRelative;
                    resultData_update.put(right_relative,df.format(b)+"%");
                    if(b>0){
                        resultData_update.put(right_status,2);
                    }else{
                        resultData_update.put(right_status,3);
                    }
                }
            }
            resultData.put("update_relative",resultData_update);

   //     异常
            Map<String, Object> resultData_exception = new HashMap<>();
            params = new HashMap<>();
            params.put("quantity","2");
            int exceptionNum = dataInfoDayMapper.relativeDau(reportParamsVO,params);
            resultData_exception.put(left,exceptionNum);
            if(exceptionNum==0){
                resultData_exception.put(left_relative,"-");
                resultData_exception.put(left_status,0);
            }else if(reportParamsVO.getBetweenDay()>30L){
                resultData_exception.put(left_relative,"-");
                resultData_exception.put(left_status,0);
            }else{
                int exceptionNumRelative = dataInfoDayMapper.relativeDau(reportParamsVORelative,params);
                if(exceptionNumRelative==0){
                    resultData_exception.put(left_relative,"-");
                    resultData_exception.put(left_status,0);
                }else if(exceptionNumRelative==exceptionNum){
                    resultData_exception.put(left_relative,"持平");
                    resultData_exception.put(left_status,1);
                }else{
                    double v = (exceptionNum - exceptionNumRelative)* 100.0d / exceptionNumRelative;
                    String format = df.format(v);
                    resultData_exception.put(left_relative,format+"%");
                    if(v>0){
                        resultData_exception.put(left_status,2);
                    }else{
                        resultData_exception.put(left_status,3);
                    }
                }
            }
            //潜在风险
            if(reportParamsVO.getOs().equals("2")){
                int exceptionNumExce = dataInfoDayMapper.relativeNew(reportParamsVO);
                resultData_exception.put(right,exceptionNumExce);
                if(exceptionNumExce==0){
                    resultData_exception.put(right_relative,"-");
                    resultData_exception.put(right_status,0);
                }else if(reportParamsVO.getBetweenDay()>30L){
                    resultData_exception.put(right_relative,"-");
                    resultData_exception.put(right_status,0);
                }else{
                    int exceptionNumExceRelative = dataInfoDayMapper.relativeNew(reportParamsVORelative);
                    if(exceptionNumExceRelative==0){
                        resultData_exception.put(right_relative,"-");
                        resultData_exception.put(right_status,0);
                    }else if(exceptionNumExceRelative==exceptionNumExce){
                        resultData_exception.put(right_relative,"持平");
                        resultData_exception.put(right_status,1);
                    }else{
                        double b = (exceptionNumExce - exceptionNumExceRelative)* 100.0d / exceptionNumExceRelative;
                        resultData_exception.put(right_relative,df.format(b)+"%");
                        if(b>0){
                            resultData_exception.put(right_status,2);
                        }else{
                            resultData_exception.put(right_status,3);
                        }
                    }
                }
            }
            resultData.put("exception_relative",resultData_exception);
       // }
        return ResultGenerator.genSuccessResult(resultData);
    }

    @Override
    public RestResult dashboardChart(ReportParamsVO reportParamsVO) {
        defaultAppkeys(reportParamsVO);
        ChartVo chartVo = null;
        if(reportParamsVO.getDateType().equals("1")&&reportParamsVO.getBetweenDay()==0){//查询实时且是同一天，按照小时维度查询
            if(reportParamsVO.getReportName().equals("new_user_chart")){
                List<String> column = null;
                List<String> name = null;
                if(reportParamsVO.getOs().equals("2")){//Android
                    column = Arrays.asList("normal", "exception", "potential_risk");
                    name = Arrays.asList("正常新增", "异常新增", "潜在风险新增");
                }else{
                    column = Arrays.asList("normal", "exception");
                    name = Arrays.asList("正常新增", "异常新增");
                }
                chartVo = ChartVo.builder().reportName("新增")
                        .column(column)
                        .name(name)
                        .key(keys)
                        .build();
                Map<String, String> params = new HashMap<>();
                params.put("device_status","1");
                params.put("quantity_normal","1");
                params.put("quantity_exception","2");
                params.put("quantity_potential_risk","5");
                List<Map> maps = dataInfoHourMapper.dashboardChart(reportParamsVO, params);
                parseDateChart(chartVo,maps,"hour");

            }else if(reportParamsVO.getReportName().equals("dau_chart")){
                List<String> column = null;
                List<String> name = null;
                if(reportParamsVO.getOs().equals("2")){//Android
                    column = Arrays.asList("normal", "exception", "potential_risk");
                    name = Arrays.asList("正常DAU", "异常DAU", "潜在风险DAU");
                }else{
                    column = Arrays.asList("normal", "exception");
                    name = Arrays.asList("正常DAU", "异常DAU");
                }
                chartVo = ChartVo.builder().reportName("DAU")
                        .column(column)
                        .name(name)
                        .key(keys)
                        .build();
                Map<String, String> params = new HashMap<>();
                params.put("quantity_normal","1");
                params.put("quantity_exception","2");
                params.put("quantity_potential_risk","5");
                List<Map> maps = dataInfoHourMapper.dashboardChartDAU(reportParamsVO, params);
                parseDateChart(chartVo,maps,"hour");

            }else if(reportParamsVO.getReportName().equals("update_chart")){
                List<String> column = null;
                List<String> name = null;
                if(reportParamsVO.getOs().equals("2")){//Android
                    column = Arrays.asList("normal", "exception", "potential_risk");
                    name = Arrays.asList("正常更新", "异常更新", "潜在风险更新");
                }else{
                    column = Arrays.asList("normal", "exception");
                    name = Arrays.asList("正常更新", "异常更新");
                }
                chartVo = ChartVo.builder().reportName("更新")
                        .column(column)
                        .name(name)
                        .key(keys)
                        .build();
                Map<String, String> params = new HashMap<>();
                params.put("appIsUpdate","1");
                params.put("quantity_normal","1");
                params.put("quantity_exception","2");
                params.put("quantity_potential_risk","5");
                List<Map> maps = dataInfoHourMapper.dashboardChart(reportParamsVO, params);
                parseDateChart(chartVo,maps,"hour");

            }else if(reportParamsVO.getReportName().equals("exception_chart")){
                List<String> column = null;
                List<String> name = null;
                if(reportParamsVO.getOs().equals("2")){//Android
                    column = Arrays.asList("exception_new_user", "exception_dau", "exception_update", "potential_risk");
                    name = Arrays.asList("异常新增", "异常DAU","异常更新", "潜在风险");
                }else{
                    column = Arrays.asList("exception_new_user", "exception_dau", "exception_update");
                    name = Arrays.asList("异常新增", "异常DAU","异常更新");
                }
                chartVo = ChartVo.builder().reportName("异常")
                        .column(column)
                        .name(name)
                        .key(keys)
                        .build();
                List<Map> maps = dataInfoHourMapper.dashboardChartForException(reportParamsVO);
                parseDateChart(chartVo,maps,"hour");
            }
        }else{//按天查询
            List<DateTime> dateTimes = DateUtil.rangeToList(DateUtil.parse(reportParamsVO.getStartDate(), DatePattern.NORM_DATE_PATTERN).toJdkDate()
                    , DateUtil.parse(reportParamsVO.getEndDate(), DatePattern.NORM_DATE_PATTERN).toJdkDate(),
                    DateField.DAY_OF_YEAR);
            List<String> day_keys = new ArrayList<>();
            for (DateTime dateTime : dateTimes) {
                day_keys.add(dateTime.toString(DatePattern.NORM_DATE_PATTERN));
            }

            if(reportParamsVO.getReportName().equals("new_user_chart")){
                List<String> column = null;
                List<String> name = null;
                if(reportParamsVO.getOs().equals("2")){//Android
                    column = Arrays.asList("normal", "exception", "potential_risk");
                    name = Arrays.asList("正常新增", "异常新增", "潜在风险新增");
                }else{
                    column = Arrays.asList("normal", "exception");
                    name = Arrays.asList("正常新增", "异常新增");
                }
                chartVo = ChartVo.builder().reportName("新增")
                        .column(column)
                        .name(name)
                        .key(day_keys)
                        .build();
                Map<String, String> params = new HashMap<>();
                params.put("device_status","1");
                params.put("quantity_normal","1");
                params.put("quantity_exception","2");
                params.put("quantity_potential_risk","5");
                List<Map> maps = dataInfoDayMapper.dashboardChart(reportParamsVO, params);
                parseDateChart(chartVo,maps,"ds");
            }else if(reportParamsVO.getReportName().equals("dau_chart")){
                List<String> column = null;
                List<String> name = null;
                if(reportParamsVO.getOs().equals("2")){//Android
                    column = Arrays.asList("normal", "exception", "potential_risk");
                    name = Arrays.asList("正常DAU", "异常DAU", "潜在风险DAU");
                }else{
                    column = Arrays.asList("normal", "exception");
                    name = Arrays.asList("正常DAU", "异常DAU");
                }
                chartVo = ChartVo.builder().reportName("DAU")
                        .column(column)
                        .name(name)
                        .key(day_keys)
                        .build();
                Map<String, String> params = new HashMap<>();
                params.put("quantity_normal","1");
                params.put("quantity_exception","2");
                params.put("quantity_potential_risk","5");
                List<Map> maps = dataInfoDayMapper.dashboardChartDAU(reportParamsVO, params);
                parseDateChart(chartVo,maps,"ds");
            }else if(reportParamsVO.getReportName().equals("update_chart")){
                List<String> column = null;
                List<String> name = null;
                if(reportParamsVO.getOs().equals("2")){//Android
                    column = Arrays.asList("normal", "exception", "potential_risk");
                    name = Arrays.asList("正常更新", "异常更新", "潜在风险更新");
                }else{
                    column = Arrays.asList("normal", "exception");
                    name = Arrays.asList("正常更新", "异常更新");
                }
                chartVo = ChartVo.builder().reportName("更新")
                        .column(column)
                        .name(name)
                        .key(day_keys)
                        .build();
                Map<String, String> params = new HashMap<>();
                params.put("appIsUpdate","1");
                params.put("quantity_normal","1");
                params.put("quantity_exception","2");
                params.put("quantity_potential_risk","5");
                List<Map> maps = dataInfoDayMapper.dashboardChart(reportParamsVO, params);
                parseDateChart(chartVo,maps,"ds");
            }else if(reportParamsVO.getReportName().equals("exception_chart")){
                List<String> column = null;
                List<String> name = null;
                if(reportParamsVO.getOs().equals("2")){//Android
                    column = Arrays.asList("exception_new_user", "exception_dau", "exception_update", "potential_risk");
                    name = Arrays.asList("异常新增", "异常DAU","异常更新", "潜在风险");
                }else{
                    column = Arrays.asList("exception_new_user", "exception_dau", "exception_update");
                    name = Arrays.asList("异常新增", "异常DAU","异常更新");
                }
                chartVo = ChartVo.builder().reportName("异常")
                        .column(column)
                        .name(name)
                        .key(day_keys)
                        .build();
                List<Map> maps = dataInfoDayMapper.dashboardChartForException(reportParamsVO);
                parseDateChart(chartVo,maps,"ds");
            }
        }
        return ResultGenerator.genSuccessResult(chartVo);
    }

    public ReportParamsVO defaultAppkeys(ReportParamsVO reportParamsVO){
        if(StringUtils.isEmpty(reportParamsVO.getAppkeys())){//sql中appkey为必传，当用户未创建app时，处理返回全0数据
            reportParamsVO.setAppkeys("-1");
        }
        return reportParamsVO;
    }
    @Override
    public RestResult channelQualityTopChart(ReportParamsVO reportParamsVO, String type) {
        defaultAppkeys(reportParamsVO);
            List<String> column = Arrays.asList("normal", "exception");
            List<String> name = Arrays.asList("正常新增", "异常新增");
        ChartVo chartVo = ChartVo.builder().reportName("渠道质量排行")
                .column(column)
                .name(name)
                .build();
        List<Map> maps = dataInfoDayMapper.channelQualityTopChart(reportParamsVO,type);
        parseChannelQualityTopChart(chartVo,maps,"cid",reportParamsVO);
        //计算百分比
        List<List<Object>> val = chartVo.getVal();
        if(!CollectionUtils.isEmpty(val)){
            List<String> key = chartVo.getKey();
            List<List<Object>> subVals = new ArrayList<>();
            List<Integer> totalVals = new ArrayList<>();
            for (int i = 0; i < key.size(); i++) {//计算每一列的总和
                Integer subTotal = 0;
                for (List<Object> objects : val) {
                    subTotal+=Integer.valueOf(objects.get(i).toString());
                }
                totalVals.add(i,subTotal);
            }

            for (List<Object> objects : val) {//每一列的值/每一列的和
                List<Object> subVal = new ArrayList<>();
                for (int i = 0; i < objects.size(); i++) {
                    Integer sub_total = totalVals.get(i);
                    if(sub_total == 0 || Integer.valueOf(objects.get(i).toString())==0){
                        subVal.add(0.00);
                    }else{
                        subVal.add(df.format(Integer.valueOf(objects.get(i).toString())*100.0/sub_total));
                    }
                }
                subVals.add(subVal);
            }
            if(type.equals("num")){
                chartVo.setSubVal(subVals);
            }else{
                chartVo.setVal(subVals);
                chartVo.setSubVal(val);
            }
        }
        return ResultGenerator.genSuccessResult(chartVo);
    }

    @Override
    public RestResult channelQualityTopList(ReportParamsVO reportParamsVO) {
        defaultAppkeys(reportParamsVO);
        List<String> name = Arrays.asList("渠道名称", "渠道ID","新增设备总数","正常新增总数","正常新增占比","异常新增总数","异常新增占比");
        List<String> column = Arrays.asList("channel_alias", "cid","num_total","num_normal","rate_normal","num_exception","rate_exception");
        List<String> orderByColumns = Arrays.asList("num_total","num_normal","rate_normal","num_exception","rate_exception");
        ListVo listVo = ListVo.builder().reportName("渠道质量排行数据汇总")
                .column(column)
                .name(name)
                .orderByColumns(orderByColumns)
                .build();
        PageHelper.startPage(reportParamsVO.getPageNum(), reportParamsVO.getPageSize(), reportParamsVO.getOrderBy());
        List<Map> maps = dataInfoDayMapper.channelQualityTopList(reportParamsVO);
        if(!CollectionUtils.isEmpty(maps)){
            List<Channel>  channels = channelMapper.findByAppkey(reportParamsVO.getAppkeys());
            Map<String, String> channelAliasMap = new HashMap<>();
            for (Channel channel : channels) {
                channelAliasMap.put(channel.getCid(),channel.getChannelAlias());
            }
            for (Map map : maps) {

                map.put("rate_exception",df.format(map.get("rate_exception")));//格式化小数点
                map.put("rate_normal", df.format(map.get("rate_normal")));//格式化小数点
                Object cid = map.get("cid");
                map.put("channel_alias",channelAliasMap.get(cid)==null?cid:channelAliasMap.get(cid));
            }
            PageInfo<Map> pageInfo = new PageInfo<>(maps);
            //查汇总
            Map totalMap = dataInfoDayMapper.channelQualityTopListTotal(reportParamsVO);
            totalMap.put("rate_exception",df.format(totalMap.get("rate_exception")));//格式化小数点
            totalMap.put("rate_normal", df.format(totalMap.get("rate_normal")));//格式化小数点
            totalMap.put("channel_alias","汇总");
            totalMap.put("cid","");
            maps.add(0,totalMap);
            listVo.setVal(maps);
            listVo.setTotal(pageInfo.getTotal());
        }else{
            Map totalMap = new HashMap();
            for (String s : column) {
                if(s.equals("channel_alias")){
                    totalMap.put(s,"汇总");
                }else if(s.equals("cid")){
                    totalMap.put(s,"");
                }else if(s.startsWith("num_")){
                    totalMap.put(s,0);
                }else if(s.startsWith("rate_")){
                    totalMap.put(s,0.00);
                }else{
                    totalMap.put(s,0);
                }
            }
            maps.add(0,totalMap);
            listVo.setVal(maps);
            listVo.setTotal(0);
        }
        return ResultGenerator.genSuccessResult(listVo);
    }

    @Override
    public RestResult statisticAnalysisChart(ReportParamsVO reportParamsVO, Long loginUserId) {
        if(StringUtils.isEmpty(reportParamsVO.getViewcolumns())){
            return ResultGenerator.genSuccessResult();
        }
        User user = userMapper.selectByPrimaryKey(loginUserId);
        authReportParams(reportParamsVO,user);
        if(CollectionUtils.isEmpty(reportParamsVO.getAppkeyAndCidsList())){//如果是空，那么一定查不到数据，appkey和cid必有值
            return ResultGenerator.genSuccessResult();
        }
        Example viewColumnExample = new Example(ViewColumn.class);
        List<String> viewcolumnList= Arrays.asList(reportParamsVO.getViewcolumns().split(","));
        Example.Criteria criteria = viewColumnExample.createCriteria();
        criteria.andEqualTo("menu","statisticAnalysis");
        criteria.andIn("fieldcode",viewcolumnList);
        viewColumnExample.and(criteria);
        List<ViewColumn> viewColumns = viewColumnMapper.selectByExample(viewColumnExample);
        Map<String, String> viewColumnMap = new HashMap<>();

        //处理返回的表头
        String idColumn = null;//维度的主字段
        List<String> name = new ArrayList<>();//中文表头
        List<String> column = new ArrayList<>();//字段
        for (ViewColumn viewColumn : viewColumns) {
            column.add(viewColumn.getFieldcode());
            name.add(viewColumn.getFieldname());
            viewColumnMap.put(viewColumn.getFieldcode(),viewColumn.getFieldname());
        }

        ChartVo chartVo = ChartVo.builder()
                .column(column)
                .name(name)
                .build();

        String reportName = reportParamsVO.getReportName();
        List<Map> maps = new ArrayList<>();
        //除日期外按默认总量升序
        String orderBy = null;
        if(!reportName.equals("statisticAnalysisByDate")){
            orderBy = "volume_dose_normal desc";
        }
        viewColumnMap.put("orderByColumn",orderBy);
         if(reportName.equals("statisticAnalysisByDate")){
            idColumn = "ds";
            chartVo.setReportName("分天趋势图");
            viewColumnMap.put("idColumn",idColumn);
            maps = dataInfoDayMapper.statisticAnalysis(reportParamsVO,viewColumnMap);
            List<DateTime> dateTimes = DateUtil.rangeToList(DateUtil.parse(reportParamsVO.getStartDate(), DatePattern.NORM_DATE_PATTERN).toJdkDate()
                    , DateUtil.parse(reportParamsVO.getEndDate(), DatePattern.NORM_DATE_PATTERN).toJdkDate(),
                    DateField.DAY_OF_YEAR);
            List<String> day_keys = new ArrayList<>();
            for (DateTime dateTime : dateTimes) {
                day_keys.add(dateTime.toString(DatePattern.NORM_DATE_PATTERN));
            }
            chartVo.setKey(day_keys);
            parseDateChart(chartVo,maps,idColumn);
        }else if(reportName.equals("statisticAnalysisByApp")){
            idColumn = "appkey";
            chartVo.setReportName("应用趋势图");
            viewColumnMap.put("idColumn",idColumn);
            maps = dataInfoDayMapper.statisticAnalysis(reportParamsVO,viewColumnMap);
             List<String> appkeys = getIdColumns(maps,idColumn);
             chartVo.setKey(appkeys);
             parseDateChart(chartVo,maps,idColumn);
             //处理chartVo中key的appkey
             if (!CollectionUtils.isEmpty(appkeys)) {
                 Example example = new Example(App.class);
                 Example.Criteria criteria1 = example.createCriteria();
                 criteria1.andIn("appkey",appkeys);
                 example.and(criteria1);
                 List<App> apps = appMapper.selectByExample(example);
                 Map<String, String> appNameMap = new HashMap<>();
                 for (App app : apps) {
                     appNameMap.put(app.getAppkey(),app.getAppName());
                 }
                 List<String> keys = chartVo.getKey();
                 List<String> appkeyList = new ArrayList<>();
                 for (String key : keys) {
                     appkeyList.add(appNameMap.get(key)==null?key:appNameMap.get(key));
                 }
                 chartVo.setKey(appkeyList);
             }
         }else if(reportName.equals("statisticAnalysisByChannel")){
            idColumn = "cid,appkey";//特殊处理，因为cid和appkey是关联的，不同app下可能有相同cid
            chartVo.setReportName("渠道趋势图");
            viewColumnMap.put("idColumn",idColumn);
            maps = dataInfoDayMapper.statisticAnalysis(reportParamsVO,viewColumnMap);
            idColumn = "cid_appkey";//特殊格式
            //处理maps中的cid和appkey为特殊格式
             List<String> cidFlag = new ArrayList<>();
             for (Map map : maps) {
                 String s = new StringBuilder().append(map.get("cid")).append("_").append(map.get("appkey")).toString();
                 map.put(idColumn,s);
                 cidFlag.add(s);
            }
            chartVo.setKey(cidFlag);
            parseDateChart(chartVo,maps,idColumn);
            //处理chartVo中key的cid
             // 渠道的替换名称要按照cid+appkey来匹配别名
             List<String> cids = new ArrayList<>();
             Map<String, String> authUserCids = getAuthUserCids(loginUserId, reportParamsVO.getOs());
             for (String key : cidFlag) {
                 cids.add(authUserCids.get(key)==null?key:authUserCids.get(key));
             }
             chartVo.setKey(cids);
         }else if(reportName.equals("statisticAnalysisBySdkVersion")){
             idColumn = "sdk_version";
             chartVo.setReportName("SDK版本趋势图");
             viewColumnMap.put("idColumn",idColumn);
             maps = dataInfoDayMapper.statisticAnalysis(reportParamsVO,viewColumnMap);
             chartVo.setKey(getIdColumns(maps,idColumn));
             parseDateChart(chartVo,maps,idColumn);
         }else if(reportName.equals("statisticAnalysisByAppVersion")){
             idColumn = "app_version";
             chartVo.setReportName("App版本趋势图");
             viewColumnMap.put("idColumn",idColumn);
             maps = dataInfoDayMapper.statisticAnalysis(reportParamsVO,viewColumnMap);
             chartVo.setKey(getIdColumns(maps,idColumn));
             parseDateChart(chartVo,maps,idColumn);
         }else if(reportName.equals("statisticAnalysisBySysVersion")){
             idColumn = "system_version";
             chartVo.setReportName("操作系统版本趋势图");
             viewColumnMap.put("idColumn",idColumn);
             maps = dataInfoDayMapper.statisticAnalysis(reportParamsVO,viewColumnMap);
             chartVo.setKey(getIdColumns(maps,idColumn));
             parseDateChart(chartVo,maps,idColumn);
         }else if(reportName.equals("statisticAnalysisByModelVersion")){
             idColumn = "model_equip";
             chartVo.setReportName("设备型号趋势图");
             viewColumnMap.put("idColumn",idColumn);
             maps = dataInfoDayMapper.statisticAnalysis(reportParamsVO,viewColumnMap);
             chartVo.setKey(getIdColumns(maps,idColumn));
             parseDateChart(chartVo,maps,idColumn);
         }else if(reportName.equals("statisticAnalysisByBrandVersion")){
             idColumn = "brand_equip";
             chartVo.setReportName("设备品牌趋势图");
             viewColumnMap.put("idColumn",idColumn);
             maps = dataInfoDayMapper.statisticAnalysis(reportParamsVO,viewColumnMap);
             chartVo.setKey(getIdColumns(maps,idColumn));
             parseDateChart(chartVo,maps,idColumn);
         }

        return ResultGenerator.genSuccessResult(chartVo);
    }

    private List<String> getIdColumns(List<Map> maps, String idColumn) {
        List<String> keys = new ArrayList<>();
        for (Map map : maps) {
            keys.add(map.get(idColumn).toString());
        }
        return keys;
    }


    /**
     * 功能描述:处理用户报表的应用、渠道、版本等参数的权限
     * @author liyin
     * @date 2021/11/4
     */

    public ReportParamsVO authReportParams(ReportParamsVO reportParamsVO, User user) {
        if(reportParamsVO.getOs().equals("1")){//iOS 没有取到之分
            if(CollectionUtils.isEmpty(reportParamsVO.getAppkeyAndCidsList())){//appkey为空则填充全部(除删除和停用app)
                List<App> apps = authServiceImpl.getAppByUserAndOs(user,reportParamsVO.getOs(),false);
                List<AppkeyAndCids> appkeyAndCidsList =new ArrayList<>();
                for (App app : apps) {
                        appkeyAndCidsList.add(new AppkeyAndCids(app.getAppkey(),null));
                }
                reportParamsVO.setAppkeyAndCidsList(appkeyAndCidsList);
            }
        }else{//Android
            if(CollectionUtils.isEmpty(reportParamsVO.getAppkeyAndCidsList())){//appkey为空则填充全部(除删除和停用app)
                List<App> apps = authServiceImpl.getAppByUserAndOs(user,reportParamsVO.getOs(),false);
                List<AppkeyAndCids> appkeyAndCidsList =new ArrayList<>();
                for (App app : apps) {
                    List<String> cids = channelMapper.findNormalByAppkey(app.getAppkey());//直接查，上面的app是根据权限过滤过的
                    if(!CollectionUtils.isEmpty(cids)){//如果cid查到了就加入报表参数条件，没查到说明没同步或者压根没有，所以不同查该appkey
                        appkeyAndCidsList.add(new AppkeyAndCids(app.getAppkey(),cids));
                    }
                }
                reportParamsVO.setAppkeyAndCidsList(appkeyAndCidsList);
            }else{
                List<AppkeyAndCids> appkeyAndCidsList = reportParamsVO.getAppkeyAndCidsList();
                List<AppkeyAndCids> appkeyAndCidsRemove = new ArrayList<>();
                for (AppkeyAndCids appkeyAndCids : appkeyAndCidsList) {//appkey不为空则填充appkey下的cids(cids为null情况下)
                    if(CollectionUtils.isEmpty(appkeyAndCids.getCids())){
                        List<String> cids = channelMapper.findNormalByAppkey(appkeyAndCids.getAppkey());
                        if(CollectionUtils.isEmpty(cids)){//cids=null则移除该appkeyAndCids对象
                            appkeyAndCidsRemove.add(appkeyAndCids);
                        }else{//查到的cid不为null则填充到对象
                            appkeyAndCids.setCids(cids);
                        }
                    }
                }
                if(!CollectionUtils.isEmpty(appkeyAndCidsRemove)){
                    appkeyAndCidsList.removeAll(appkeyAndCidsRemove);
                }
            }
        }

//        if(StringUtils.isEmpty(reportParamsVO.getAppkeys())){//查询当前用户拥有的app
//            List<App> apps = authServiceImpl.getAppByUserAndOs(user,reportParamsVO.getOs(),false);
//            List<String> appkeys = new ArrayList<>();
//            for (App app : apps) {
//                appkeys.add(new StringBuilder("'").append(app.getAppkey()).append("'").toString());
//            }
//            if(!CollectionUtils.isEmpty(apps)){
//                reportParamsVO.setAppkeys(StrUtil.join(",", appkeys));
//            }else{
//                throw new CustomException(-200,"暂无数据");//如果连app都没有的话，就可以直接返回没数据终止查询
//            }
//        }
//        //渠道必传，因为如果有些渠道状态是关闭/删除状态，那么就需要过滤报表数据
//        if(StringUtils.isEmpty(reportParamsVO.getCids())){//查询当前用户拥有的cid
//            List<Channel> channels = authServiceImpl.getChannelByUserAndOs(user,reportParamsVO.getOs(),true);
//            List<String> cids = new ArrayList<>();
//            for (Channel channel : channels) {
//                cids.add(new StringBuilder("'").append(channel.getCid()).append("'").toString());
//            }
//            if(!CollectionUtils.isEmpty(channels)){
//                reportParamsVO.setCids(StrUtil.join(",", cids));
//            }else{
//                reportParamsVO.setCids("'-9999'");//如果查不到渠道，就传-9999表示没有数据，防止web还没同步渠道就被报表查出来
//            }
//        }
        return reportParamsVO;
    }

    @Override
    public RestResult statisticAnalysisList(ReportParamsVO reportParamsVO, Long loginUserId) {
        if(StringUtils.isEmpty(reportParamsVO.getViewcolumns())){
            return ResultGenerator.genSuccessResult();
        }
        User user = userMapper.selectByPrimaryKey(loginUserId);
        authReportParams(reportParamsVO,user);
        if(CollectionUtils.isEmpty(reportParamsVO.getAppkeyAndCidsList())){//如果是空，那么一定查不到数据，appkey和cid必有值
            return ResultGenerator.genSuccessResult();
        }
        Example viewColumnExample = new Example(ViewColumn.class);
        List<String> viewcolumnList= Arrays.asList(reportParamsVO.getViewcolumns().split(","));
        Example.Criteria criteria = viewColumnExample.createCriteria();
        criteria.andEqualTo("menu","statisticAnalysis");
        criteria.andIn("fieldcode",viewcolumnList);
        viewColumnExample.and(criteria);
        List<ViewColumn> viewColumns = viewColumnMapper.selectByExample(viewColumnExample);
        List<String> orderByColumns = viewcolumnList;
        //List<String> orderByColumns = Arrays.asList("num_normal","rate_normal");
        Map<String, String> viewColumnMap = new HashMap<>();

        //处理返回的表头
        String idColumn = null;//维度的主字段
        List<String> name = new ArrayList<>();//中文表头
        List<String> column = new ArrayList<>();//字段
        for (ViewColumn viewColumn : viewColumns) {
            column.add(viewColumn.getFieldcode());
            name.add(viewColumn.getFieldname());
            viewColumnMap.put(viewColumn.getFieldcode(),viewColumn.getFieldname());
        }
        String reportName = reportParamsVO.getReportName();
        List<Map> maps = new ArrayList<>();
        Map<String, Object> totalMap = new HashMap<>();
        PageInfo<Map> pageInfo = null;
        //除日期外按默认总量升序
        String orderBy = reportParamsVO.getOrderBy();
        if(!reportName.equals("statisticAnalysisByDate")){
            orderBy = StringUtils.isEmpty(reportParamsVO.getOrderBy())?"volume_dose desc":reportParamsVO.getOrderBy();
        }
        ListVo listVo = ListVo.builder()
                .column(column)
                .name(name)
                .orderByColumns(orderByColumns)
                .currentOrderByCloumn(orderBy)
                .build();
        PageHelper.startPage(reportParamsVO.getPageNum(), reportParamsVO.getPageSize(),orderBy);

        if(reportName.equals("statisticAnalysisByDate")){

            idColumn = "ds";
            column.add(0,idColumn);
            name.add(0,"日期");
            listVo.setReportName("分天数据详情");
            viewColumnMap.put("idColumn",idColumn);
            maps = dataInfoDayMapper.statisticAnalysis(reportParamsVO,viewColumnMap);
            pageInfo = new PageInfo<>(maps);
            //查询总数
        }else if(reportName.equals("statisticAnalysisByApp")){
            idColumn = "appkey";
            column.add(0,idColumn);
            name.add(0,"应用");
            listVo.setReportName("应用数据详情");
            viewColumnMap.put("idColumn",idColumn);
            maps = dataInfoDayMapper.statisticAnalysis(reportParamsVO,viewColumnMap);
            //查询总数
            pageInfo = new PageInfo<>(maps);
            List<String> appkeys = reportParamsVO.getAppkeyAndCidsList().stream().map(AppkeyAndCids::getAppkey).collect(Collectors.toList());
            replaceAppkey(StrUtil.join(",",appkeys),idColumn,maps);
        }else if(reportName.equals("statisticAnalysisByChannel")){
            //以下代码顺序很重要~
            idColumn = "cid,appkey";//查报表时
            listVo.setReportName("渠道数据详情");
            viewColumnMap.put("idColumn",idColumn);
            maps = dataInfoDayMapper.statisticAnalysis(reportParamsVO,viewColumnMap);
            //查询总数
            pageInfo = new PageInfo<>(maps);
            idColumn = "cid_appkey";//替换渠道名时
            //处理maps中的cid和appkey为特殊格式
            for (Map map : maps) {
                map.put(idColumn,new StringBuilder().append(map.get("cid")).append("_").append(map.get("appkey")).toString());
            }
            //cid换名
            replaceCid(idColumn,maps,loginUserId,reportParamsVO.getOs());
            idColumn = "cid";//查汇总数据时
            column.add(0,idColumn);
            name.add(0,"渠道");
        }else if(reportName.equals("statisticAnalysisBySdkVersion")){
            idColumn = "sdk_version";
            column.add(0,idColumn);
            name.add(0,"SDK版本");
            listVo.setReportName("SDK版本数据详情");
            viewColumnMap.put("idColumn",idColumn);
            maps = dataInfoDayMapper.statisticAnalysis(reportParamsVO,viewColumnMap);
            //查询总数
            pageInfo = new PageInfo<>(maps);
        }else if(reportName.equals("statisticAnalysisByAppVersion")){
            idColumn = "app_version";
            column.add(0,idColumn);
            name.add(0,"App版本");
            listVo.setReportName("App版本数据详情");
            viewColumnMap.put("idColumn",idColumn);
            maps = dataInfoDayMapper.statisticAnalysis(reportParamsVO,viewColumnMap);
            //查询总数
            pageInfo = new PageInfo<>(maps);
        }else if(reportName.equals("statisticAnalysisBySysVersion")){
            idColumn = "system_version";
            column.add(0,idColumn);
            name.add(0,"操作系统");
            listVo.setReportName("操作系统数据详情");
            viewColumnMap.put("idColumn",idColumn);
            maps = dataInfoDayMapper.statisticAnalysis(reportParamsVO,viewColumnMap);
            //查询总数
            pageInfo = new PageInfo<>(maps);
        }else if(reportName.equals("statisticAnalysisByModelVersion")){
            idColumn = "model_equip";
            column.add(0,idColumn);
            name.add(0,"设备型号");
            listVo.setReportName("设备型号数据详情");
            viewColumnMap.put("idColumn",idColumn);
            maps = dataInfoDayMapper.statisticAnalysis(reportParamsVO,viewColumnMap);
            //查询总数
            pageInfo = new PageInfo<>(maps);
        }else if(reportName.equals("statisticAnalysisByBrandVersion")){
            idColumn = "brand_equip";
            column.add(0,idColumn);
            name.add(0,"设备品牌");
            listVo.setReportName("设备品牌数据详情");
            viewColumnMap.put("idColumn",idColumn);
            maps = dataInfoDayMapper.statisticAnalysis(reportParamsVO,viewColumnMap);
            //查询总数
            pageInfo = new PageInfo<>(maps);
        }

        if(!CollectionUtils.isEmpty(maps)){
            totalMap = dataInfoDayMapper.statisticAnalysisTotal(reportParamsVO,viewColumnMap);
        }else{
            totalMap = new HashMap();
            for (String s : column) {
                if(s.equals(idColumn)){
                    totalMap.put(s,"汇总");
                }else if(s.startsWith("num_")){
                    totalMap.put(s,0);
                }else if(s.startsWith("rate_")){
                    totalMap.put(s,0.00);
                }else{
                    totalMap.put(s,0);
                }
            }
        }
        maps.add(0,totalMap);
        //格式化“率”
        for (Map map : maps) {
            for (String view : viewcolumnList) {
                if(view.startsWith("rate_")){
                    map.put(view,df.format(map.get(view)==null?0:map.get(view)));
                }
            }
        }
        listVo.setVal(maps);
        listVo.setTotal(pageInfo.getTotal());
        return ResultGenerator.genSuccessResult(listVo);
    }

    /**
     * 功能描述:替换cid，凡是要替换cid名称，需要处理成@code<cid_appkey>组合格式
     */
    private void replaceCid(String idColumn, List<Map> maps, Long loginUserId, String os) {
        Map<String, String> authUserCids = getAuthUserCids(loginUserId, os);
        for (Map map : maps) {
            map.put("cid",authUserCids.get(map.get(idColumn))==null?map.get("cid"):authUserCids.get(map.get(idColumn)));
        }
    }

    /**
     * 功能描述:替换cid，凡是要替换cid名称，需要处理成@code<cid_appkey>组合格式
     */
    public Map<String,String> getAuthUserCids(Long userId,String os){
        List<Map<String,Object>> channelDTOs =channelServiceImpl.findChannelsByAppkey(userId,null,os);
        Map<String, String> map = new HashMap<>();
        for (Map<String, Object> channelDTO : channelDTOs) {
            map.put(new StringBuilder(channelDTO.get("cid").toString()).append("_").append(channelDTO.get("appkey").toString()).toString(),channelDTO.get("channelAlias").toString());
        }
        return map;
    }

    public void replaceAppkey(String appkeys, String idColumn , List<Map> maps){
        Example example = new Example(App.class);
        Example.Criteria criteria1 = example.createCriteria();
        criteria1.andIn("appkey",Arrays.asList(appkeys.split(",")));
        example.and(criteria1);
        List<App> apps = appMapper.selectByExample(example);
        Map<String, String> appNameMap = new HashMap<>();
        for (App app : apps) {
            appNameMap.put(app.getAppkey(),app.getAppName());
        }
        for (Map map : maps) {
            map.put(idColumn,appNameMap.get(map.get(idColumn))==null?map.get(idColumn):appNameMap.get(map.get(idColumn)));
        }
    }


    public void parseChannelQualityTopChart(ChartVo chartVo,List<Map> maps,String idColumn,ReportParamsVO reportParamsVO){
        if(CollectionUtils.isEmpty(maps)){
            return;
        }
        List<String> keys = new ArrayList<>();
        for (Map map : maps) {
            Object cid = map.get(idColumn);
            keys.add(cid.toString());
        }
        chartVo.setKey(keys);//cid，用完以后需要替换成渠道名
        List<String> columns = chartVo.getColumn();//指标字段
        List<List<Object>> vals = new ArrayList<>();
        for (String column : columns) {
            List<Object> val= new ArrayList<>();
            for (String key : keys) {
                for (Map map : maps) {
                    if(map.get(idColumn)!=null&&map.get(idColumn).equals(key)){
                        val.add(map.get(column));
                        break;
                    }
                }
            }
            vals.add(val);
        }
        chartVo.setVal(vals);
        List<Channel>  channels = channelMapper.findByAppkey(reportParamsVO.getAppkeys());
        Map<String, String> channelAliasMap = new HashMap<>();
        for (Channel channel : channels) {
            channelAliasMap.put(channel.getCid(),channel.getChannelAlias());
        }
        List<String> keysAlias = new ArrayList<>();
        for (String key : keys) {
            if(channelAliasMap.get(key)==null){
                keysAlias.add(key);
            }else{
                keysAlias.add(channelAliasMap.get(key));
            }
        }
        chartVo.setKey(keysAlias);//cid替换成渠道别名
    }
    public void parseDateChart(ChartVo chartVo,List<Map> maps,String idColumn){
        List<String> keys = chartVo.getKey();//日期或时
        if(keys==null)keys=new ArrayList<>();
        List<String> columns = chartVo.getColumn();//指标字段
        List<List<Object>> vals = new ArrayList<>();
        for (String column : columns) {
            List<Object> val= new ArrayList<>();
            for (String key : keys) {
                Boolean flag =true;
                for (Map map : maps) {
                    if(map.get(idColumn)!=null&&map.get(idColumn).equals(key)){
                        if(column.startsWith("rate_")){
                            val.add(df.format(map.get(column)));
                        }else{
                            val.add(map.get(column));
                        }
                        flag=false;
                        break;
                    }
                }
                if(flag){
                    if(column.startsWith("rate_")){
                        val.add(0.00);
                    }else{
                        val.add(0);
                    }
                }
            }
            vals.add(val);
        }
        chartVo.setVal(vals);
    }


}
