package org.jeecg.ctop.material.service.impl;


import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.DateUtils;
import org.jeecg.ctop.material.constants.Check;
import org.jeecg.ctop.material.entity.vo.KuaiShouAccountPieVo;
import org.jeecg.ctop.material.entity.vo.KuaiShouOperateAccountVo;
import org.jeecg.ctop.material.entity.vo.KuaiShouOperateGroupVo;
import org.jeecg.ctop.material.entity.vo.KuaiShouOperateProjectVo;
import org.jeecg.ctop.material.entity.vo.KuaiShouOperateVo;
import org.jeecg.ctop.material.mapper.MaterialStareMapper;
import org.jeecg.ctop.material.service.MaterialStareService;
import org.jeecg.ctop.material.service.support.DashboardQuerySupport;
import org.jeecg.ctop.material.utils.LinkUtil;
import org.jeecg.ctop.material.utils.ListPageUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 盯盘接口
 */
@Slf4j
@Service
public class MaterialStareServiceImpl implements MaterialStareService {

    @Resource
    MaterialStareMapper materialStareMapper;

    @Resource
    DashboardQuerySupport dashboardQuerySupport;

    /**
     * @param mediaType 媒体类型 1-头条 2-快手
     * @param type      查询类型 1-汇总 2-运营个人
     * @param userId
     * @param startTime
     * @param startTime
     * @description:数据总览-快手-运营经理
     * @author: zianY
     * @time: 2022/2/15
     */
    @Override
    public Result kuaiShousumData(String mediaType, String type, String startTime, String endTime, String userId) {
        long stratDate = DateUtils.getDateInteger(startTime);
        long endDate = DateUtils.getDateInteger(endTime);
        long nowDate = DateUtils.getDateInteger(DateUtils.getDate("yyyy-MM-dd"));
        boolean currentDayOnly = isCurrentDayOnly(stratDate, endDate, nowDate);
        //查询当前人员所有下级
        Set<String> operatorUserIds = getAffiliateId(userId);
        //头条
        if (StringUtils.equals(mediaType, "1")) {
            //return Result.successMsg("暂无头条数据。",null);
            //汇总
            if (StringUtils.equals(type, "1")) {
                //查询一天数据时 查询时报
                if (currentDayOnly) {
                    Map resultMap = new HashMap<>();
                    //时报
                    List<Map> todayList = materialStareMapper.getBytedanceCostHourlyByUserIdList(stratDate, endDate, operatorUserIds);
                    long time = DateUtils.getDateInteger(DateUtils.addDayParse(Long.toString(endDate), -1));
                    List<Map> yesterdayList = materialStareMapper.getBytedanceCostHourlyByUserIdList(time, time, operatorUserIds);
                    resultMap.put("todayList", todayList);
                    resultMap.put("yesterdayList", yesterdayList);
                    return Result.successMsg("查询-头条-时报-汇总。", resultMap);
                }
                //多天 数据
                // 日报
                List<Map> dailyList = materialStareMapper.getBytedanceCostDailyByUserIdList(stratDate, endDate, operatorUserIds);
                return Result.successMsg("查询-头条-日报-汇总成功。", dailyList);
            }

            //运营个人
            if (StringUtils.equals(type, "2")) {
                if (currentDayOnly) {
                    //时报 消耗前5
                    List<JSONObject> userList = materialStareMapper.getBytedanceCostByTop5HourList(stratDate, endDate, operatorUserIds);
                    List<Map> resultList = new ArrayList<>();
                    for (JSONObject jsonObject : userList) {
                        Map map = new HashMap();
                        Set<String> userSet = new HashSet<String>() {{
                            add(jsonObject.getString("user_id"));
                        }};
                        List<Map> usertopList = materialStareMapper.getBytedanceCostHourlyByUserIdList(stratDate, endDate, userSet);
                        map.put("userName", jsonObject.getString("userName"));
                        map.put("data", usertopList);
                        resultList.add(map);
                    }
                    return Result.successMsg("查询-头条-时报-运营个人消耗top5成功。", resultList);
                }
                //日报 消耗前5
                List<JSONObject> userList = materialStareMapper.getBytedanceCostByTop5DailyList(stratDate, endDate, operatorUserIds);
                List<Map> resultList = new ArrayList<>();
                for (JSONObject jsonObject : userList) {
                    Map map = new HashMap();
                    Set<String> userSet = new HashSet<String>() {{
                        add(jsonObject.getString("user_id"));
                    }};
                    //日报
                    List<Map> usertopList = materialStareMapper.getBytedanceCostDailyByUserIdList(stratDate, endDate, userSet);
                    map.put("userName", jsonObject.getString("userName"));
                    map.put("data", usertopList);
                    resultList.add(map);
                }
                return Result.successMsg("查询-快手-日报-运营个人消耗top5成功。", resultList);
            }
        }
        //快手
        if (StringUtils.equals(mediaType, "2")) {
            //汇总
            if (StringUtils.equals(type, "1")) {
                //查询一天数据时 查询时报
                if (currentDayOnly) {
                    Map resultMap = new HashMap<>();
                    //时报
                    List<Map> todayList = materialStareMapper.getKuaiShouCostHourlyByUserIdList(stratDate, endDate, operatorUserIds);
                    long time = DateUtils.getDateInteger(DateUtils.addDayParse(Long.toString(endDate), -1));
                    List<Map> yesterdayList = materialStareMapper.getKuaiShouCostHourlyByUserIdList(time, time, operatorUserIds);
                    resultMap.put("todayList", todayList);
                    resultMap.put("yesterdayList", yesterdayList);
                    return Result.successMsg("查询-快手-时报-汇总。", resultMap);
                }
                //多天 数据
                // 日报
                List<Map> dailyList = materialStareMapper.getKuaiShouCostDailyByUserIdList(stratDate, endDate, operatorUserIds);
                return Result.successMsg("查询-快手-日报-汇总成功。", dailyList);

                //运营个人
            } else if (StringUtils.equals(type, "2")) {
                if (currentDayOnly) {
                    //时报 消耗前5
                    List<JSONObject> userList = materialStareMapper.getKuaiShouCostByTop5HourList(stratDate, endDate, operatorUserIds);
                    List<Map> resultList = new ArrayList<>();
                    for (JSONObject jsonObject : userList) {
                        Map map = new HashMap();
                        Set<String> userSet = new HashSet<String>() {{
                            add(jsonObject.getString("user_id"));
                        }};
                        List<Map> usertopList = materialStareMapper.getKuaiShouCostHourlyByUserIdList(stratDate, endDate, userSet);
                        map.put("userName", jsonObject.getString("userName"));
                        map.put("data", usertopList);
                        resultList.add(map);
                    }
                    return Result.successMsg("查询-快手-时报-运营个人消耗top5成功。", resultList);
                }

                //日报 消耗前5
                List<JSONObject> userList = materialStareMapper.getKuaiShouCostByTop5DailyList(stratDate, endDate, operatorUserIds);
                List<Map> resultList = new ArrayList<>();
                for (JSONObject jsonObject : userList) {
                    Map map = new HashMap();
                    Set<String> userSet = new HashSet<String>() {{
                        add(jsonObject.getString("user_id"));
                    }};
                    List<Map> usertopList = materialStareMapper.getKuaiShouCostDailyByUserIdList(stratDate, endDate, userSet);
                    map.put("userName", jsonObject.getString("userName"));
                    map.put("data", usertopList);
                    resultList.add(map);
                }
                return Result.successMsg("查询-快手-日报-运营个人消耗top5成功。", resultList);
            }
        }
        if (StringUtils.equals(mediaType, "16")) {
            if (StringUtils.equals(type, "1")) {
                if (currentDayOnly) {
                    Map resultMap = new HashMap<>();
                    List<Map> todayList = materialStareMapper.getAdqCostHourlyByUserIdList(stratDate, endDate, operatorUserIds);
                    long time = DateUtils.getDateInteger(DateUtils.addDayParse(Long.toString(endDate), -1));
                    List<Map> yesterdayList = materialStareMapper.getAdqCostHourlyByUserIdList(time, time, operatorUserIds);
                    resultMap.put("todayList", todayList);
                    resultMap.put("yesterdayList", yesterdayList);
                    return Result.successMsg("查询-腾讯-时报-汇总。", resultMap);
                }
                List<Map> dailyList = materialStareMapper.getAdqCostDailyByUserIdList(stratDate, endDate, operatorUserIds);
                return Result.successMsg("查询-腾讯-日报-汇总成功。", dailyList);
            }
            if (StringUtils.equals(type, "2")) {
                if (currentDayOnly) {
                    List<JSONObject> userList = materialStareMapper.getAdqCostByTop5HourList(stratDate, endDate, operatorUserIds);
                    List<Map> resultList = new ArrayList<>();
                    for (JSONObject jsonObject : userList) {
                        Map map = new HashMap();
                        Set<String> userSet = new HashSet<String>() {{
                            add(jsonObject.getString("user_id"));
                        }};
                        List<Map> usertopList = materialStareMapper.getAdqCostHourlyByUserIdList(stratDate, endDate, userSet);
                        map.put("userName", jsonObject.getString("userName"));
                        map.put("data", usertopList);
                        resultList.add(map);
                    }
                    return Result.successMsg("查询-腾讯-时报-运营个人消耗top5成功。", resultList);
                }
                List<JSONObject> userList = materialStareMapper.getAdqCostByTop5DailyList(stratDate, endDate, operatorUserIds);
                List<Map> resultList = new ArrayList<>();
                for (JSONObject jsonObject : userList) {
                    Map map = new HashMap();
                    Set<String> userSet = new HashSet<String>() {{
                        add(jsonObject.getString("user_id"));
                    }};
                    List<Map> usertopList = materialStareMapper.getAdqCostDailyByUserIdList(stratDate, endDate, userSet);
                    map.put("userName", jsonObject.getString("userName"));
                    map.put("data", usertopList);
                    resultList.add(map);
                }
                return Result.successMsg("查询-腾讯-日报-运营个人消耗top5成功。", resultList);
            }
        }
        return null;
    }

    /**
     * @param mediaType 媒体类型 1-头条 2-快手
     * @param startTime
     * @param endTime
     * @param userId
     * @description: 数据总览-快手-运营个人
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/3/3
     */
    @Override
    public Result kuaiShousumDataPersonal(String mediaType, String startTime, String endTime, String userId) {

        long stratDate = DateUtils.getDateInteger(startTime);
        long endDate = DateUtils.getDateInteger(endTime);
        long nowDate = DateUtils.getDateInteger(DateUtils.getDate("yyyy-MM-dd"));
        boolean currentDayOnly = isCurrentDayOnly(stratDate, endDate, nowDate);
        Set<String> userSet = new HashSet<String>() {{
            add(userId);
        }};


        //查询用户角色
        String roleCode = materialStareMapper.getRoleCodeByUserId(userId);
        //判断是否运营相关角色,并获取媒体类型
        if (!Check.isNull(roleCode)) {
            if ("touTiaoOperationManager".equals(roleCode)) {
                mediaType = "1";
            } else if ("kuaishouOperationManager".equals(roleCode)) {
                mediaType = "2";
            } else if (roleCode.toLowerCase().contains("perat")) {
                String leaderRoleCode = materialStareMapper.getOperatLeaderRole(userId);
                if (!Check.isNull(leaderRoleCode)) {
                    if ("touTiaoOperationManager".equals(leaderRoleCode)) {
                        mediaType = "1";
                    } else if ("kuaishouOperationManager".equals(leaderRoleCode)) {
                        mediaType = "2";
                    }
                }
            } else {
                return Result.successMsg("非运营相关角色,不显示数据", "");
            }
        }

        //头条
        if (StringUtils.equals(mediaType, "1")) {
            //查询一天数据时 查询时报
            if (currentDayOnly) {
                Map resultMap = new HashMap<>();
                //时报
                List<Map> todayList = materialStareMapper.getBytedanceCostHourlyByUserIdList(stratDate, endDate, userSet);
                long time = DateUtils.getDateInteger(DateUtils.addDayParse(Long.toString(endDate), -1));
                List<Map> yesterdayList = materialStareMapper.getBytedanceCostHourlyByUserIdList(time, time, userSet);
                resultMap.put("todayList", todayList);
                resultMap.put("yesterdayList", yesterdayList);
                return Result.successMsg("查询运营个人-时报-汇总。", resultMap);
            }
            //多天 数据
            // 日报
            List<Map> dailyList = materialStareMapper.getBytedanceCostDailyByUserIdList(stratDate, endDate, userSet);
            return Result.successMsg("查询运营个人-日报-汇总成功。", dailyList);
        }
        //快手
        if (StringUtils.equals(mediaType, "2")) {
            //查询一天数据时 查询时报
            if (currentDayOnly) {
                Map resultMap = new HashMap<>();
                //时报
                List<Map> todayList = materialStareMapper.getKuaiShouCostHourlyByUserIdList(stratDate, endDate, userSet);
                long time = DateUtils.getDateInteger(DateUtils.addDayParse(Long.toString(endDate), -1));
                List<Map> yesterdayList = materialStareMapper.getKuaiShouCostHourlyByUserIdList(time, time, userSet);
                resultMap.put("todayList", todayList);
                resultMap.put("yesterdayList", yesterdayList);
                return Result.successMsg("查询运营个人-时报-汇总。", resultMap);
            }
            //多天 数据
            // 日报
            List<Map> dailyList = materialStareMapper.getKuaiShouCostDailyByUserIdList(stratDate, endDate, userSet);
            return Result.successMsg("查询运营个人-日报-汇总成功。", dailyList);
        }
        if (StringUtils.equals(mediaType, "16")) {
            if (currentDayOnly) {
                Map resultMap = new HashMap<>();
                List<Map> todayList = materialStareMapper.getAdqCostHourlyByUserIdList(stratDate, endDate, userSet);
                long time = DateUtils.getDateInteger(DateUtils.addDayParse(Long.toString(endDate), -1));
                List<Map> yesterdayList = materialStareMapper.getAdqCostHourlyByUserIdList(time, time, userSet);
                resultMap.put("todayList", todayList);
                resultMap.put("yesterdayList", yesterdayList);
                return Result.successMsg("查询运营个人-时报-汇总。", resultMap);
            }
            List<Map> dailyList = materialStareMapper.getAdqCostDailyByUserIdList(stratDate, endDate, userSet);
            return Result.successMsg("查询运营个人-日报-汇总成功。", dailyList);
        }
        return null;
    }


    /**
     * @param mediaType 媒体类型 1-头条 2-快手
     * @param startTime
     * @param endTime
     * @param userId
     * @description: 快手-运营组数据
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/2/15
     */
    @Override
    public Result kuaiShouOperateDateTotal(String mediaType, String startTime, String endTime, String userId) {
        Map resultMap = new HashMap();
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");
        Set<String> operatorUserIds = null;

        try {

            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            // ==>> 20220202
            String now = sdf.format(new Date());
            long nowDate = Long.valueOf(now);
            int nowHour = DateUtils.getNowHour();
            //昨天时间
            long time = DateUtils.getDateInteger(DateUtils.addDayParse(now, -1));

            //查询当前人员所有下级
            operatorUserIds = getAffiliateId(userId);

            //头条
            if (mediaType.equals("1")) {
                long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
                long endDate = Long.valueOf(DateUtils.getDateInteger(endTime));
                boolean currentDay = startDate == endDate && startDate == nowDate;
                Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
                long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
                long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));
                JSONObject projectUserSummary = materialStareMapper.getBytedanceOperateProjectUserSummary(startDate, endDate, operatorUserIds);
                JSONObject sectionSummary = currentDay
                        ? materialStareMapper.getBytedanceTotalCost(startDate, endDate, nowHour, operatorUserIds)
                        : materialStareMapper.getBytedanceOperateSummary(startDate, endDate, operatorUserIds);
                Double tCost = getJsonDouble(sectionSummary, "totalCost");
                resultMap.put("sectionCost", tCost);
                if (currentDay) {
                    JSONObject compareSummary = materialStareMapper.getOperateTodayYesterdaySummary(
                            "application.bytedance_advertiser_report_hourly_dw",
                            "stat_datetime",
                            "cost",
                            "hour",
                            nowDate,
                            nowDate,
                            nowHour,
                            time,
                            operatorUserIds
                    );
                    double todayCost = getJsonDouble(compareSummary, "todayCost");
                    resultMap.put("todayCost", todayCost);
                    double yesterdayCost = getJsonDouble(compareSummary, "yesterdayCost");
                    resultMap.put("compare", formatRate(todayCost, yesterdayCost, decimalFormat));
                } else {
                    JSONObject periodSummary = materialStareMapper.getBytedancePeriodCostSummary(startDate, endDate, lastTimeStart, lastTimeEnd, operatorUserIds);
                    double currentCost = getJsonDouble(periodSummary, "currentCost");
                    double lastCost = getJsonDouble(periodSummary, "lastCost");
                    resultMap.put("todayCost", currentCost);
                    resultMap.put("compare", formatRate(currentCost, lastCost, decimalFormat));
                }
                int activeUserNum = getJsonInt(projectUserSummary, "userNum");
                Double userAverageAccount = safeDivide(getJsonDouble(sectionSummary, "accountNum"), activeUserNum);
                Double userAveragecost = safeDivide(tCost, activeUserNum);
                DecimalFormat df = new DecimalFormat("#.000");
                resultMap.put("userAverageAccount", new Double(Math.ceil(userAverageAccount)).intValue());
                resultMap.put("userAveragecost", userAveragecost == 0.0 ? 0 : df.format(userAveragecost));
                resultMap.put("projectNum", String.valueOf(getJsonInt(projectUserSummary, "projectNum")));
            }

            //快手
            if (mediaType.equals("2")) {
                long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
                long endDate = Long.valueOf(DateUtils.getDateInteger(endTime));
                boolean currentDay = startDate == endDate && startDate == nowDate;
                Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
                long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
                long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));
                JSONObject summary = currentDay
                        ? materialStareMapper.getKuaiShouTotalCost(startDate, endDate, nowHour, operatorUserIds)
                        : materialStareMapper.getKuaiShouOperateSummary(startDate, endDate, operatorUserIds);
                JSONObject projectUserSummary = currentDay
                        ? materialStareMapper.getKuaiShouOperateProjectUserSummary(startDate, endDate, nowHour, operatorUserIds)
                        : materialStareMapper.getKuaiShouOperateSummary(startDate, endDate, operatorUserIds);
                double sectionCost = getJsonDouble(summary, "totalCost");
                resultMap.put("sectionCost", sectionCost);
                if (currentDay) {
                    JSONObject compareSummary = materialStareMapper.getOperateTodayYesterdaySummary(
                            "application.kuaishou_account_report_hourly_dw",
                            "stat_date",
                            "charge",
                            "hour",
                            nowDate,
                            nowDate,
                            nowHour,
                            time,
                            operatorUserIds
                    );
                    double todayCost = getJsonDouble(compareSummary, "todayCost");
                    resultMap.put("todayCost", todayCost);
                    double yesterdayCost = getJsonDouble(compareSummary, "yesterdayCost");
                    resultMap.put("compare", formatRate(todayCost, yesterdayCost, decimalFormat));
                } else {
                    JSONObject periodSummary = materialStareMapper.getKuaiShouPeriodCostSummary(startDate, endDate, lastTimeStart, lastTimeEnd, operatorUserIds);
                    double currentCost = getJsonDouble(periodSummary, "currentCost");
                    double lastCost = getJsonDouble(periodSummary, "lastCost");
                    resultMap.put("todayCost", currentCost);
                    resultMap.put("compare", formatRate(currentCost, lastCost, decimalFormat));
                }
                int activeUserNum = getJsonInt(projectUserSummary, "userNum");
                Double userAverageAccount = safeDivide(getJsonDouble(summary, "accountNum"), activeUserNum);
                Double userAveragecost = safeDivide(sectionCost, activeUserNum);
                DecimalFormat df = new DecimalFormat("#.000");
                resultMap.put("userAverageAccount", new Double(Math.ceil(userAverageAccount)).intValue());
                resultMap.put("userAveragecost", df.format(userAveragecost));
                resultMap.put("projectNum", String.valueOf(getJsonInt(projectUserSummary, "projectNum")));
            }
            if (mediaType.equals("16")) {
                long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
                long endDate = Long.valueOf(DateUtils.getDateInteger(endTime));
                boolean currentDay = startDate == endDate && startDate == nowDate;
                Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
                long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
                long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));
                JSONObject totalCost = currentDay
                        ? materialStareMapper.getAdqTotalCost(startDate, endDate, nowHour, operatorUserIds)
                        : materialStareMapper.getAdqTotalCostDaily(startDate, endDate, operatorUserIds);
                Double tCost = getJsonDouble(totalCost, "totalCost");
                resultMap.put("sectionCost", tCost);
                if (currentDay) {
                    JSONObject jsonObjectNow = materialStareMapper.getAdqTotalCost(nowDate, nowDate, nowHour, operatorUserIds);
                    double todayCost = getJsonDouble(jsonObjectNow, "totalCost");
                    resultMap.put("todayCost", todayCost);
                    JSONObject jsonObjectYesterday = materialStareMapper.getAdqTotalCost(time, time, nowHour, operatorUserIds);
                    double yesterdayCost = getJsonDouble(jsonObjectYesterday, "totalCost");
                    resultMap.put("compare", formatRate(todayCost, yesterdayCost, decimalFormat));
                } else {
                    JSONObject periodSummary = materialStareMapper.getAdqPeriodCostSummary(startDate, endDate, lastTimeStart, lastTimeEnd, operatorUserIds);
                    double currentCost = getJsonDouble(periodSummary, "currentCost");
                    double lastCost = getJsonDouble(periodSummary, "lastCost");
                    resultMap.put("todayCost", currentCost);
                    resultMap.put("compare", formatRate(currentCost, lastCost, decimalFormat));
                }
                Double userAverageAccount = safeDivide(getJsonDouble(totalCost, "accountNum"), safeSize(operatorUserIds));
                Double userAveragecost = safeDivide(tCost, safeSize(operatorUserIds));
                DecimalFormat df = new DecimalFormat("#.000");
                resultMap.put("userAverageAccount", new Double(Math.ceil(userAverageAccount)).intValue());
                resultMap.put("userAveragecost", userAveragecost == 0.0 ? 0 : df.format(userAveragecost));
                String projectNum = currentDay
                        ? materialStareMapper.getAdqOperatorProjectNumHourly(startDate, endDate, nowHour, operatorUserIds)
                        : materialStareMapper.getAdqOperatorProjectNum(startDate, endDate, operatorUserIds);
                resultMap.put("projectNum", projectNum);
            }

            alignGroupSummaryWithGroupRows(resultMap, userId, mediaType, startTime, endTime);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.successMsg("查询成功", resultMap);
    }

    /**
     * @param mediaType 媒体类型 1-头条 2-快手
     * @param startTime
     * @param endTime
     * @param userId
     * @description: 运营个人数据
     * @return: org.jeecg.common.api.vo.Result<com.alibaba.fastjson.JSONObject>
     * @author: zianY
     * @time: 2022/3/3
     */
    @Override
    public Result kuaiShouOperateDateTotalPersonal(String mediaType, String startTime, String endTime, String userId) {
        if ("1".equals(mediaType)) {
            return bytedanceOperateDateTotalPersonal(startTime, endTime, userId);
        }
        if ("16".equals(mediaType)) {
            return adqOperateDateTotalPersonal(startTime, endTime, userId);
        }
        Map resultMap = new HashMap();
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");
        long stratDate = DateUtils.getDateInteger(startTime);
        long endDate = DateUtils.getDateInteger(endTime);

        try {
            Set<String> userSet = new HashSet<String>() {{
                add(userId);
            }};
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            String now = sdf.format(new Date());
            long nowDate = Long.valueOf(now);
            int nowHour = DateUtils.getNowHour();
            long yesterday = DateUtils.getDateInteger(DateUtils.addDayParse(now, -1));
            Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
            long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
            long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));
            long monthFirstDay = Long.valueOf(DateUtils.getFirstDayByMonth());

            JSONObject todaySummary = materialStareMapper.getKuaiShouTodayYesterdayCostSummary(nowDate, yesterday, nowHour, userSet);
            double todayCost = getJsonDouble(todaySummary, "todayCost");
            double yesterdayCost = getJsonDouble(todaySummary, "yesterdayCost");
            resultMap.put("todayCost", todayCost);
            resultMap.put("todayCompare", formatRate(todayCost, yesterdayCost, decimalFormat));

            boolean currentDayOnly = isCurrentDayOnly(stratDate, endDate, nowDate);
            double timeCost;
            double lastCost;
            if (currentDayOnly) {
                timeCost = todayCost;
                lastCost = yesterdayCost;
            } else {
                JSONObject periodSummary = materialStareMapper.getKuaiShouPeriodCostSummary(stratDate, endDate, lastTimeStart, lastTimeEnd, userSet);
                timeCost = getJsonDouble(periodSummary, "currentCost");
                lastCost = getJsonDouble(periodSummary, "lastCost");
            }
            resultMap.put("timeCost", timeCost);
            resultMap.put("timeCompare", formatRate(timeCost, lastCost, decimalFormat));

            JSONObject chargedSummary = materialStareMapper.getKuaiShouAccountCharged(monthFirstDay, nowDate, userSet);
            resultMap.put("directCharged", Check.isNull(chargedSummary) ? "0" : chargedSummary.getString("directCharged"));
            resultMap.put("contractCharged", Check.isNull(chargedSummary) ? "0" : chargedSummary.getString("contractCharged"));

            JSONObject monthCost = materialStareMapper.getKuaiShouAccountCostMonth(userId, monthFirstDay, nowDate);
            resultMap.put("monthCost", Check.isNull(monthCost) ? "0" : monthCost.getString("cost"));

            JSONObject userName = materialStareMapper.getKuaiShouUserByUserId(userId);
            resultMap.put("userName", Check.isNull(userName) ? "-" : userName.getString("userName"));

            String companyId = materialStareMapper.getUserCompanyByUserId(userId);
            JSONObject rankSummary = materialStareMapper.getKuaiShouPersonalRankSummary(monthFirstDay, nowDate, companyId, userId);
            resultMap.put("userRankTotalNum", getJsonInt(rankSummary, "totalNum"));
            resultMap.put("userIdRank", rankSummary == null ? null : rankSummary.getString("serialNumber"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.successMsg("查询运营个人数据成功", resultMap);
    }

    public Result bytedanceOperateDateTotalPersonal(String startTime, String endTime, String userId) {
        Map resultMap = new HashMap();
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");

        long stratDate = DateUtils.getDateInteger(startTime);
        long endDate = DateUtils.getDateInteger(endTime);

        try {
            Set<String> userSet = new HashSet<String>() {{
                add(userId);
            }};

            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            // ==>> 20220202
            String now = sdf.format(new Date());
            long nowDate = Long.valueOf(now);
            int nowHour = DateUtils.getNowHour();
            //昨天时间
            long time = DateUtils.getDateInteger(DateUtils.addDayParse(now, -1));

            //上阶段时间
            Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
            long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
            long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));
            JSONObject todaySummary = materialStareMapper.getBytedanceTodayYesterdayCostSummary(nowDate, time, nowHour, userSet);
            double todayCost = getJsonDouble(todaySummary, "todayCost");
            double yesterdayCost = getJsonDouble(todaySummary, "yesterdayCost");
            resultMap.put("todayCost", todayCost);
            resultMap.put("todayCompare", formatRate(todayCost, yesterdayCost, decimalFormat));

            boolean currentDayOnly = isCurrentDayOnly(stratDate, endDate, nowDate);
            double timeCost;
            double lastCost;
            if (currentDayOnly) {
                timeCost = todayCost;
                lastCost = yesterdayCost;
            } else {
                JSONObject periodSummary = materialStareMapper.getBytedancePeriodCostSummary(stratDate, endDate, lastTimeStart, lastTimeEnd, userSet);
                timeCost = getJsonDouble(periodSummary, "currentCost");
                lastCost = getJsonDouble(periodSummary, "lastCost");
            }
            resultMap.put("timeCost", timeCost);
            resultMap.put("timeCompare", formatRate(timeCost, lastCost, decimalFormat));

            //当前月份的框返 和 激励
            // 当前月份第一天
            long monthFirstDay = Long.valueOf(DateUtils.getFirstDayByMonth());

            //当前月消耗
            JSONObject monthCost = materialStareMapper.getBytedanceAccountCostMonth(userId, monthFirstDay, nowDate);
            resultMap.put("monthCost", Check.isNull(monthCost) ? "0" : monthCost.getString("cost"));

            //用户
            JSONObject userName = materialStareMapper.getKuaiShouUserByUserId(userId);
            resultMap.put("userName", Check.isNull(userName) ? "-" : userName.getString("userName"));

            String companyId = materialStareMapper.getUserCompanyByUserId(userId);
            JSONObject rankSummary = materialStareMapper.getBytedancePersonalRankSummary(monthFirstDay, nowDate, companyId, userId);
            resultMap.put("userRankTotalNum", getJsonInt(rankSummary, "totalNum"));
            resultMap.put("userIdRank", rankSummary == null ? null : rankSummary.getString("serialNumber"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.successMsg("查询运营个人数据成功", resultMap);
    }

    public Result adqOperateDateTotalPersonal(String startTime, String endTime, String userId) {
        Map resultMap = new HashMap();
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");
        long stratDate = DateUtils.getDateInteger(startTime);
        long endDate = DateUtils.getDateInteger(endTime);
        try {
            Set<String> userSet = new HashSet<String>() {{
                add(userId);
            }};
            String now = new SimpleDateFormat("yyyyMMdd").format(new Date());
            long nowDate = Long.valueOf(now);
            int nowHour = DateUtils.getNowHour();
            long yesterday = DateUtils.getDateInteger(DateUtils.addDayParse(now, -1));
            Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
            long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
            long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));

            JSONObject todaySummary = materialStareMapper.getAdqTodayYesterdayCostSummary(nowDate, yesterday, nowHour, userSet);
            double todayCost = getJsonDouble(todaySummary, "todayCost");
            double yesterdayCost = getJsonDouble(todaySummary, "yesterdayCost");
            resultMap.put("todayCost", todayCost);
            resultMap.put("todayCompare", formatRate(todayCost, yesterdayCost, decimalFormat));

            boolean currentDayOnly = isCurrentDayOnly(stratDate, endDate, nowDate);
            double timeCost;
            double lastCost;
            if (currentDayOnly) {
                timeCost = todayCost;
                lastCost = yesterdayCost;
            } else {
                JSONObject periodSummary = materialStareMapper.getAdqPeriodCostSummary(stratDate, endDate, lastTimeStart, lastTimeEnd, userSet);
                timeCost = getJsonDouble(periodSummary, "currentCost");
                lastCost = getJsonDouble(periodSummary, "lastCost");
            }
            resultMap.put("timeCost", timeCost);
            resultMap.put("timeCompare", formatRate(timeCost, lastCost, decimalFormat));
            resultMap.put("directCharged", "0");
            resultMap.put("contractCharged", "0");
            resultMap.put("monthCost", "0");
            JSONObject userName = materialStareMapper.getKuaiShouUserByUserId(userId);
            resultMap.put("userName", Check.isNull(userName) ? "-" : userName.getString("userName"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.successMsg("查询运营个人数据成功", resultMap);
    }

    /**
     * @param pageNum
     * @param pageSize
     * @param startTime
     * @param endTime
     * @param userId
     * @description: 运营数据详情-master
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/2/16
     */
    @Override
    public Result getKuaiShouOperateInfo(Integer pageNum, int pageSize, String mediaType, String startTime, String endTime, String userId) {
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");

        String roleCode = materialStareMapper.getRoleCodeByUserId(userId);
        Set<String> operatorUserIds = new HashSet<>();

        try {
            if ("admin".equals(roleCode)) {
                //所有运营
                List<KuaiShouOperateGroupVo> allOperationManagerList = materialStareMapper.getOperationManagerUser("perat");
                List<String> allManagerList = allOperationManagerList.stream().map(KuaiShouOperateGroupVo::getUserId).collect(Collectors.toList());
                operatorUserIds = new HashSet<>(allManagerList);
            } else if (roleCode.contains("OperationManager")) {
                //查询当前人员所有下级
                operatorUserIds = getAffiliateId(userId);
            }

            //2022-02-15 ==>> 20220215
            long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
            long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));
            //上阶段时间
            Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
            long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
            long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));

            long now = Long.valueOf(DateUtils.getDateInteger(DateUtils.getDate("yyyy-MM-dd")));
            PageHelper.startPage(pageNum, pageSize);
            List<KuaiShouOperateVo> listOperate = loadOperatePageData(mediaType, startDate, entDate, now, operatorUserIds);
            enrichOperateList(listOperate, mediaType, startDate, entDate, now, lastTimeStart, lastTimeEnd, decimalFormat);

            PageInfo<KuaiShouOperateVo> pageInfo = new PageInfo<>(listOperate);
            return Result.successMsg("运营数据查询成功。", pageInfo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.errorMsg("哎呀,查询失败了。");
    }

    @Override
    public Result exportKuaiShouOperateInfo(String startTime, String endTime, String mediaType, String userId, HttpServletResponse response) {
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");
        String roleCode = materialStareMapper.getRoleCodeByUserId(userId);
        Set<String> operatorUserIds = new HashSet<>();

        try {

            if ("admin".equals(roleCode)) {
                //所有运营
                List<KuaiShouOperateGroupVo> allOperationManagerList = materialStareMapper.getOperationManagerUser("perat");
                List<String> allManagerList = allOperationManagerList.stream().map(KuaiShouOperateGroupVo::getUserId).collect(Collectors.toList());
                operatorUserIds = new HashSet<>(allManagerList);
            } else if (roleCode.contains("OperationManager")) {
                //查询当前人员所有下级
                operatorUserIds = getAffiliateId(userId);
            }


            //2022-02-15 ==>> 20220215
            long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
            long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));
            //上阶段时间
            Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
            long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
            long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));

            long now = Long.valueOf(DateUtils.getDateInteger(DateUtils.getDate("yyyy-MM-dd")));

            List<KuaiShouOperateVo> listOperate = loadOperatePageData(mediaType, startDate, entDate, now, operatorUserIds);
            enrichOperateList(listOperate, mediaType, startDate, entDate, now, lastTimeStart, lastTimeEnd, decimalFormat);
            Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("运营数据详情", "运营数据"), KuaiShouOperateVo.class, listOperate);
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("运营数据详情.xlsx", "UTF-8"));
            workbook.write(response.getOutputStream());
            return null;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.errorMsg("哎呀,查询失败了。");
    }


    /**
     * @param pageNum
     * @param pageSize
     * @param startTime
     * @param endTime
     * @param userId
     * @description: 运营数据-项目列表
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/2/17
     */
    @Override
    public Result getKuaiShouOperateProjectInfo(Integer pageNum, int pageSize, String mediaType, String startTime, String endTime, String userId) {
        try {
            if ("16".equals(mediaType)) {
                List<KuaiShouOperateProjectVo> listOperate = getOperateProjectInfo(pageNum, pageSize, mediaType, startTime, endTime, userId);
                PageInfo<KuaiShouOperateProjectVo> pageInfo = new PageInfo<>(listOperate);
                return Result.successMsg("运营项目列表数据查询成功。", pageInfo);
            }
            long now = Long.valueOf(DateUtils.getDateInteger(DateUtils.getDate("yyyy-MM-dd")));
            Set<String> operatorUserIds = getAffiliateId(userId);
            long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
            long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));
            boolean currentDayOnly = isCurrentDayOnly(startDate, entDate, now);
            Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
            long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
            long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));
            Map<String, Object> parameterMap = new HashMap<>();
            parameterMap.put("startDate", startDate);
            parameterMap.put("endDate", entDate);
            parameterMap.put("lastTimeStart", lastTimeStart);
            parameterMap.put("lastTimeEnd", lastTimeEnd);
            parameterMap.put("userIds", operatorUserIds);
            parameterMap.put("startEqually", DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(startTime)), -7)));
            parameterMap.put("endEqually", DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(endTime)), -7)));
            if ("1".equals(mediaType)) {
                if (currentDayOnly) {
                    parameterMap.put("tableName", "application.bytedance_advertiser_report_hourly_dw");
                    parameterMap.put("hour", DateUtils.getNowHour());
                } else {
                    parameterMap.put("tableName", "application.bytedance_advertiser_report_daily_dw");
                    parameterMap.remove("hour");
                }
            } else {
                if (currentDayOnly) {
                    parameterMap.put("tableName", "application.kuaishou_account_report_hourly_dw");
                    parameterMap.put("hour", DateUtils.getNowHour());
                } else {
                    parameterMap.put("tableName", "application.kuaishou_account_report_daily_dw");
                    parameterMap.remove("hour");
                }
            }
            PageInfo<Long> projectPageInfo;
            List<KuaiShouOperateProjectVo> listOperate;
            if ("1".equals(mediaType)) {
                PageHelper.startPage(pageNum, pageSize);
                List<Long> pageProjectIds = materialStareMapper.getBytedanceProjectList(parameterMap);
                projectPageInfo = new PageInfo<>(pageProjectIds);
                if (pageProjectIds.isEmpty()) {
                    PageInfo<KuaiShouOperateProjectVo> pageInfo = new PageInfo<>();
                    pageInfo.setPageNum(projectPageInfo.getPageNum());
                    pageInfo.setPageSize(projectPageInfo.getPageSize());
                    pageInfo.setTotal(projectPageInfo.getTotal());
                    pageInfo.setList(new ArrayList<>());
                    return Result.successMsg("运营项目列表数据查询成功。", pageInfo);
                }
                parameterMap.put("projectIds", pageProjectIds);
                listOperate = sortProjectRowsByPageOrder(materialStareMapper.getBytedanceOperateProjectInfoNew(parameterMap), pageProjectIds);
            } else {
                PageHelper.startPage(pageNum, pageSize);
                List<Long> pageProjectIds = materialStareMapper.getKuaishouProjectList(parameterMap);
                projectPageInfo = new PageInfo<>(pageProjectIds);
                if (pageProjectIds.isEmpty()) {
                    PageInfo<KuaiShouOperateProjectVo> pageInfo = new PageInfo<>();
                    pageInfo.setPageNum(projectPageInfo.getPageNum());
                    pageInfo.setPageSize(projectPageInfo.getPageSize());
                    pageInfo.setTotal(projectPageInfo.getTotal());
                    pageInfo.setList(new ArrayList<>());
                    return Result.successMsg("运营项目列表数据查询成功。", pageInfo);
                }
                parameterMap.put("projectIds", pageProjectIds);
                listOperate = sortProjectRowsByPageOrder(materialStareMapper.getKuaiShouOperateProjectInfoNew(parameterMap), pageProjectIds);
                for (KuaiShouOperateProjectVo vo : listOperate) {
                    List<JSONObject> adSceneDate = JSONObject.parseArray(vo.getAdSceneDateStr(), JSONObject.class);
                    vo.setAdSceneDate(adSceneDate);
                }
            }
            Integer daysBetween = Integer.valueOf(lastTime.get("daysBetween")) + 1;
            if (daysBetween > 7) {
                for (KuaiShouOperateProjectVo projectVo : listOperate) {
                    projectVo.setEquallyRate("-");
                }
            }
            PageInfo<KuaiShouOperateProjectVo> pageInfo = new PageInfo<>();
            pageInfo.setPageNum(projectPageInfo.getPageNum());
            pageInfo.setPageSize(projectPageInfo.getPageSize());
            pageInfo.setTotal(projectPageInfo.getTotal());
            pageInfo.setList(listOperate);
            return Result.successMsg("运营项目列表数据查询成功。", pageInfo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.errorMsg("哎呀,查询失败了。");
    }


    public List<KuaiShouOperateProjectVo> exportKuaiShouOperateProjectInfo(String mediaType, String startTime, String endTime, String userId) {
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");
        long now = Long.valueOf(DateUtils.getDateInteger(DateUtils.getDate("yyyy-MM-dd")));
        List<KuaiShouOperateProjectVo> listOperate = new ArrayList<>();

        try {
            //查询当前人员所有下级
            Set<String> operatorUserIds = getAffiliateId(userId);
            //2022-02-15 ==>> 20220215
            long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
            long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));
            boolean currentDayOnly = isCurrentDayOnly(startDate, entDate, now);

            //计算环比 时间值 上阶段时间 以及 两个日期之间的 间隔天数
            Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
            long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
            long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));
            Integer daysBetween = Integer.valueOf(lastTime.get("daysBetween")) + 1;

            //计算同比 时间值 只支持7天
            long startEqually = new Long("0");
            long endEqually = new Long("0");
            if (daysBetween <= 7) {
                startEqually = DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(startTime)), -7));
                endEqually = DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(endTime)), -7));
            }

            //头条
            if (mediaType.equals("1")) {
                //查询运营数据-项目维度
                listOperate = materialStareMapper.getBytedanceOperateProjectInfo(startDate, entDate, null, operatorUserIds);
                for (KuaiShouOperateProjectVo projectInfo : listOperate) {
                    String projectId = projectInfo.getProjectId();
                    //环比 = （当前 - 上阶段 ） / 上阶段
                    String yearOnYear = "0";
                    //当天
                    int newUnitNumNow = 0;
                    int trustUnitNum = 0;
                    if (currentDayOnly) {

                        //查询当天数据


                        //时报 消费
                        //环比 = （当前 - 上阶段 ） / 上阶段
                        int hour = DateUtils.getNowHour();
                        List<KuaiShouOperateProjectVo> projectYearOnYearInfoNow = materialStareMapper.getBytedanceOperateProjectInfoHour(startDate, entDate, hour, projectId, operatorUserIds);
                        List<KuaiShouOperateProjectVo> projectYearOnYearInfoLast = materialStareMapper.getBytedanceOperateProjectInfoHour(lastTimeStart, lastTimeEnd, hour, projectId, operatorUserIds);
                        if (!Check.isNull(projectYearOnYearInfoNow) && !Check.isNull(projectYearOnYearInfoLast)) {
                            Double yearOnYearD = (projectYearOnYearInfoNow.get(0).getTotalCost() - projectYearOnYearInfoLast.get(0).getTotalCost()) / projectYearOnYearInfoNow.get(0).getTotalCost();
                            yearOnYear = decimalFormat.format(yearOnYearD);
                        }
                        projectInfo.setYearOnYear(yearOnYear);
                    } else {
                        //环比 日报
                        List<KuaiShouOperateProjectVo> projectYearOnYearInfo = materialStareMapper.getBytedanceOperateProjectInfo(lastTimeStart, lastTimeEnd, projectId, operatorUserIds);
                        if (!Check.isNull(projectYearOnYearInfo)) {
                            Double yearOnYearD = (projectInfo.getTotalCost() - projectYearOnYearInfo.get(0).getTotalCost()) / projectYearOnYearInfo.get(0).getTotalCost();
                            yearOnYear = decimalFormat.format(yearOnYearD);
                        }
                        projectInfo.setYearOnYear(yearOnYear);
                    }

                    //查询 有效 上新视频 爆款视频
                   /* JSONObject newEffect = materialStareMapper.getKuaiShouAccountBaseByUserId(null,projectInfo.getProjectId(),null,startDate,entDate);
                    projectInfo.setNewEffectNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newEffectNum"));//有效
                    projectInfo.setNewVideoNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newVideoNum"));//上新
                    projectInfo.setNewHotNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newHotNum"));//爆款
                    projectInfo.setNewUnitNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newUnitNum")+newUnitNumNow);//基建数
                    projectInfo.setTrustUnitNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("trustUnitNum")+trustUnitNum);//智能托管
*/
                    //查询 有效 上新计划 上新组
                    JSONObject newEffect = materialStareMapper.getBytedanceAccountBaseByUserId(null, projectInfo.getProjectId(), null, startDate, entDate);
                    projectInfo.setNewEffectNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newEffectNum"));//有效
                    projectInfo.setNewVideoNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newVideoNum"));//上新
                    projectInfo.setNewHotNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newHotNum"));//爆款
                    Integer unitNum = Check.isNull(newEffect) ? 0 : newEffect.getInteger("newUnitNum");//组
                    Integer unitNum1 = Check.isNull(newEffect) ? 0 : newEffect.getInteger("newUnitNum2");//组
                    newUnitNumNow = Math.addExact(unitNum, unitNum1);
                    projectInfo.setNewUnitNum(newUnitNumNow);//基建数
                    //projectInfo.setTrustUnitNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("trustUnitNum"));//智能托管
                    List<JSONObject> materailUpload = materialStareMapper.getKuaiShouMaterailUploadType(projectInfo.getProjectId(), startDate, entDate);
                    projectInfo.setAdspNum(Check.isNull(materailUpload) ? 0L : JSONObject.parseObject(materailUpload.get(0) + "").getLong("num"));//上传到助手


                    /*

                    //查看 上传到助手、媒体的素材数量 分版位花费
                    List<JSONObject> materailUpload = materialStareMapper.getKuaiShouMaterailUploadType(projectInfo.getProjectId(),startDate,entDate);
                    projectInfo.setAdspNum(Check.isNull(materailUpload) ? 0L : JSONObject.parseObject(materailUpload.get(0)+"").getLong("num"));//上传到助手
                    projectInfo.setMediaNum(Check.isNull(materailUpload) ? 0L : JSONObject.parseObject(materailUpload.get(1)+"").getLong("num"));//上传到媒体
                    //分版位
                    List<JSONObject> adSceneDate = materialStareMapper.getKuaiShouAdSceneData(projectInfo.getProjectId(),startDate,entDate);
                    projectInfo.setAdSceneDate(adSceneDate);
*/

                    //同比 日期超过 7 天 则不显示
                    String equallyRate = "-";
                    if (daysBetween <= 7) {
                        List<KuaiShouOperateProjectVo> projectEquallyInfo = materialStareMapper.getBytedanceOperateProjectInfo(startEqually, endEqually, projectId, operatorUserIds);
                        if (!Check.isNull(projectEquallyInfo)) {
                            Double equallyRateD = (projectInfo.getTotalCost() - projectEquallyInfo.get(0).getTotalCost()) / projectEquallyInfo.get(0).getTotalCost();
                            equallyRate = decimalFormat.format(equallyRateD);
                        }
                    }
                    projectInfo.setEquallyRate(equallyRate);
                }
            }
            //快手
            if (mediaType.equals("2")) {
                //查询运营数据-项目维度
                listOperate = materialStareMapper.getKuaiShouOperateProjectInfo(startDate, entDate, null, operatorUserIds);
                for (KuaiShouOperateProjectVo projectInfo : listOperate) {
                    String projectId = projectInfo.getProjectId();
                    //环比 = （当前 - 上阶段 ） / 上阶段
                    String yearOnYear = "0";
                    //当天
                    int newUnitNumNow = 0;
                    int trustUnitNum = 0;
                    if (currentDayOnly) {
                        //查询 当天有效 上新计划 上新组
                        JSONObject newEffect = materialStareMapper.getKuaiShouAccountNowBaseByUserId(null, projectInfo.getProjectId(), null, now, now);
                        newUnitNumNow = Check.isNull(newEffect) ? 0 : newEffect.getInteger("newUnitNum");//组
                        trustUnitNum = Check.isNull(newEffect) ? 0 : newEffect.getInteger("trustUnitNum");//智能托管

                        //时报 消费
                        //环比 = （当前 - 上阶段 ） / 上阶段
                        int hour = DateUtils.getNowHour();
                        List<KuaiShouOperateProjectVo> projectYearOnYearInfoNow = materialStareMapper.getKuaiShouOperateProjectInfoHour(startDate, entDate, hour, projectId, operatorUserIds);
                        List<KuaiShouOperateProjectVo> projectYearOnYearInfoLast = materialStareMapper.getKuaiShouOperateProjectInfoHour(lastTimeStart, lastTimeEnd, hour, projectId, operatorUserIds);
                        if (!Check.isNull(projectYearOnYearInfoNow) && !Check.isNull(projectYearOnYearInfoLast)) {
                            Double yearOnYearD = (projectYearOnYearInfoNow.get(0).getTotalCost() - projectYearOnYearInfoLast.get(0).getTotalCost()) / projectYearOnYearInfoNow.get(0).getTotalCost();
                            yearOnYear = decimalFormat.format(yearOnYearD);
                        }
                        projectInfo.setYearOnYear(yearOnYear);
                    } else {
                        //环比 日报
                        List<KuaiShouOperateProjectVo> projectYearOnYearInfo = materialStareMapper.getKuaiShouOperateProjectInfo(lastTimeStart, lastTimeEnd, projectId, operatorUserIds);
                        if (!Check.isNull(projectYearOnYearInfo)) {
                            Double yearOnYearD = (projectInfo.getTotalCost() - projectYearOnYearInfo.get(0).getTotalCost()) / projectYearOnYearInfo.get(0).getTotalCost();
                            yearOnYear = decimalFormat.format(yearOnYearD);
                        }
                        projectInfo.setYearOnYear(yearOnYear);
                    }

                    //查询 有效 上新视频 爆款视频
                    JSONObject newEffect = materialStareMapper.getKuaiShouAccountBaseByUserId(null, projectInfo.getProjectId(), null, startDate, entDate);
                    projectInfo.setNewEffectNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newEffectNum"));//有效
                    projectInfo.setNewVideoNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newVideoNum"));//上新
                    projectInfo.setNewHotNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newHotNum"));//爆款

                    projectInfo.setNewUnitNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newUnitNum") + newUnitNumNow);//基建数
                    projectInfo.setTrustUnitNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("trustUnitNum") + trustUnitNum);//智能托管

                    //查看 上传到助手、媒体的素材数量 分版位花费
                    List<JSONObject> materailUpload = materialStareMapper.getKuaiShouMaterailUploadType(projectInfo.getProjectId(), startDate, entDate);

                    projectInfo.setAdspNum(Check.isNull(materailUpload) ? 0L : JSONObject.parseObject(materailUpload.get(0) + "").getLong("num"));//上传到助手
                    projectInfo.setMediaNum(Check.isNull(materailUpload) ? 0L : JSONObject.parseObject(materailUpload.get(1) + "").getLong("num"));//上传到媒体

                    //分版位
                    List<JSONObject> adSceneDate = materialStareMapper.getKuaiShouAdSceneData(projectInfo.getProjectId(), startDate, entDate);
                    projectInfo.setAdSceneDate(adSceneDate);

                    //同比 日期超过 7 天 则不显示
                    String equallyRate = "-";
                    if (daysBetween <= 7) {
                        List<KuaiShouOperateProjectVo> projectEquallyInfo = materialStareMapper.getKuaiShouOperateProjectInfo(startEqually, endEqually, projectId, operatorUserIds);
                        if (!Check.isNull(projectEquallyInfo)) {
                            Double equallyRateD = (projectInfo.getTotalCost() - projectEquallyInfo.get(0).getTotalCost()) / projectEquallyInfo.get(0).getTotalCost();
                            equallyRate = decimalFormat.format(equallyRateD);
                        }
                    }
                    projectInfo.setEquallyRate(equallyRate);
                }
            }

            return listOperate;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * @param pageNum
     * @param pageSize
     * @param startTime
     * @param endTime
     * @param userId
     * @description: 运营数据-账户列表
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/2/18
     */
    @Override
    public Result getKuaiShouOperateAccountInfo(Integer pageNum, int pageSize, String startTime, String endTime, String projectId, String userId, String mediaType) {
        if ("16".equals(mediaType)) {
            return getAdqOperateAccountInfo(pageNum, pageSize, startTime, endTime, projectId, userId);
        }
        mediaType = null;
        //查询用户角色
        String roleCode = materialStareMapper.getRoleCodeByUserId(userId);
        //判断是否运营相关角色,并获取媒体类型
        if (!Check.isNull(roleCode)) {
            if ("touTiaoOperationManager".equals(roleCode)) {
                mediaType = "1";
            } else if ("kuaishouOperationManager".equals(roleCode)) {
                mediaType = "2";
            } else if (roleCode.toLowerCase().contains("perat")) {
                String leaderRoleCode = materialStareMapper.getOperatLeaderRole(userId);
                if (!Check.isNull(leaderRoleCode)) {
                    if ("touTiaoOperationManager".equals(leaderRoleCode)) {
                        mediaType = "1";
                    } else if ("kuaishouOperationManager".equals(leaderRoleCode)) {
                        mediaType = "2";
                    }
                }
            } else {
                return Result.successMsg("非运营相关角色,不显示数据", null);
            }
        }

        if ("1".equals(mediaType)) {
            return getBytedanceOperateAccountInfo(pageNum, pageSize, startTime, endTime, projectId, userId);
        } else {
            DecimalFormat decimalFormat = new DecimalFormat("0.00%");
            try {
                //查询当前人员所有下级
                Set<String> operatorUserIds = getAffiliateId(userId);
                //2022-02-15 ==>> 20220215
                long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
                long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));

                //计算环比 时间值 上阶段时间 以及 两个日期之间的 间隔天数
                Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
                long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
                long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));
                Integer daysBetween = Integer.valueOf(lastTime.get("daysBetween")) + 1;

                //计算同比 时间值 只支持7天
                long startEqually = new Long("0");
                long endEqually = new Long("0");
                if (daysBetween <= 7) {
                    startEqually = DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(startTime)), -7));
                    endEqually = DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(endTime)), -7));
                }
                long queryStartDate = buildAccountQueryStart(startDate, lastTimeStart, startEqually, daysBetween <= 7);

                PageHelper.startPage(pageNum, pageSize);
                List<KuaiShouOperateAccountVo> pageAccounts = materialStareMapper.getKuaiShouOperateAccountIdPage(startDate, entDate, projectId, operatorUserIds);
                List<Long> accountIds = pageAccounts.stream().map(KuaiShouOperateAccountVo::getAccountId).collect(Collectors.toList());
                List<KuaiShouOperateAccountVo> listOperate = accountIds.isEmpty()
                        ? new ArrayList<>()
                        : sortAccountRowsByPageOrder(materialStareMapper.getKuaiShouOperateAccountPeriodBatch(queryStartDate, entDate, startDate, entDate, lastTimeStart, lastTimeEnd, startEqually, endEqually, projectId, accountIds, operatorUserIds), accountIds);
                for (KuaiShouOperateAccountVo accountInfo : listOperate) {
                    accountInfo.setYearOnYear(formatRate(accountInfo.getTotalCost(), accountInfo.getLastTotalCost(), decimalFormat));

                    String equallyRate = "-";
                    if (daysBetween <= 7) {
                        equallyRate = formatRate(accountInfo.getTotalCost(), accountInfo.getEquallyTotalCost(), decimalFormat);
                    }
                    accountInfo.setEquallyRate(equallyRate);
                }

                PageInfo<KuaiShouOperateAccountVo> pageInfo = new PageInfo<>(pageAccounts);
                pageInfo.setList(listOperate);
                return Result.successMsg("运营账户列表数据查询成功。", pageInfo);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return Result.errorMsg("哎呀,查询失败了。");
        }
    }

    public Result getBytedanceOperateAccountInfo(Integer pageNum, int pageSize, String startTime, String endTime, String projectId, String userId) {
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");
        try {
            //查询当前人员所有下级
            Set<String> operatorUserIds = getAffiliateId(userId);
            //2022-02-15 ==>> 20220215
            long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
            long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));

            //计算环比 时间值 上阶段时间 以及 两个日期之间的 间隔天数
            Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
            long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
            long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));
            Integer daysBetween = Integer.valueOf(lastTime.get("daysBetween")) + 1;

            //计算同比 时间值 只支持7天
            long startEqually = new Long("0");
            long endEqually = new Long("0");
            if (daysBetween <= 7) {
                startEqually = DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(startTime)), -7));
                endEqually = DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(endTime)), -7));
            }
            long queryStartDate = buildAccountQueryStart(startDate, lastTimeStart, startEqually, daysBetween <= 7);
            PageHelper.startPage(pageNum, pageSize);
            List<KuaiShouOperateAccountVo> pageAccounts = materialStareMapper.getBytedanceOperateAccountIdPage(startDate, entDate, projectId, operatorUserIds);
            List<Long> accountIds = pageAccounts.stream().map(KuaiShouOperateAccountVo::getAccountId).collect(Collectors.toList());
            List<KuaiShouOperateAccountVo> listOperate = accountIds.isEmpty()
                    ? new ArrayList<>()
                    : sortAccountRowsByPageOrder(materialStareMapper.getBytedanceOperateAccountPeriodBatch(queryStartDate, entDate, startDate, entDate, lastTimeStart, lastTimeEnd, startEqually, endEqually, projectId, accountIds, operatorUserIds), accountIds);
            for (KuaiShouOperateAccountVo accountInfo : listOperate) {
                accountInfo.setYearOnYear(formatRate(accountInfo.getTotalCost(), accountInfo.getLastTotalCost(), decimalFormat));
                String equallyRate = "-";
                if (daysBetween <= 7) {
                    equallyRate = formatRate(accountInfo.getTotalCost(), accountInfo.getEquallyTotalCost(), decimalFormat);
                }
                accountInfo.setEquallyRate(equallyRate);
            }
            PageInfo<KuaiShouOperateAccountVo> pageInfo = new PageInfo<>(pageAccounts);
            pageInfo.setList(listOperate);
            return Result.successMsg("运营账户列表数据查询成功。", pageInfo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.errorMsg("哎呀,查询失败了。");
    }

    public Result getAdqOperateAccountInfo(Integer pageNum, int pageSize, String startTime, String endTime, String projectId, String userId) {
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");
        try {
            Set<String> operatorUserIds = getAffiliateId(userId);
            long startDate = Long.parseLong(String.valueOf(DateUtils.getDateInteger(startTime)));
            long entDate = Long.parseLong(String.valueOf(DateUtils.getDateInteger(endTime)));
            Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
            long lastTimeStart = Long.parseLong(String.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart"))));
            long lastTimeEnd = Long.parseLong(String.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd"))));
            Integer daysBetween = Integer.valueOf(lastTime.get("daysBetween")) + 1;
            long startEqually = 0L;
            long endEqually = 0L;
            if (daysBetween <= 7) {
                startEqually = DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(startTime)), -7));
                endEqually = DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(endTime)), -7));
            }
            long queryStartDate = buildAccountQueryStart(startDate, lastTimeStart, startEqually, daysBetween <= 7);
            PageHelper.startPage(pageNum, pageSize);
            List<KuaiShouOperateAccountVo> pageAccounts = materialStareMapper.getAdqOperateAccountIdPage(startDate, entDate, projectId, operatorUserIds);
            List<Long> accountIds = pageAccounts.stream().map(KuaiShouOperateAccountVo::getAccountId).collect(Collectors.toList());
            List<KuaiShouOperateAccountVo> listOperate = accountIds.isEmpty()
                    ? new ArrayList<>()
                    : sortAccountRowsByPageOrder(materialStareMapper.getAdqOperateAccountPeriodBatch(queryStartDate, entDate, startDate, entDate, lastTimeStart, lastTimeEnd, startEqually, endEqually, projectId, accountIds, operatorUserIds), accountIds);
            for (KuaiShouOperateAccountVo accountInfo : listOperate) {
                accountInfo.setYearOnYear(formatRate(accountInfo.getTotalCost(), accountInfo.getLastTotalCost(), decimalFormat));
                String equallyRate = "-";
                if (daysBetween <= 7) {
                    equallyRate = formatRate(accountInfo.getTotalCost(), accountInfo.getEquallyTotalCost(), decimalFormat);
                }
                accountInfo.setEquallyRate(equallyRate);
            }
            PageInfo<KuaiShouOperateAccountVo> pageInfo = new PageInfo<>(pageAccounts);
            pageInfo.setList(listOperate);
            return Result.successMsg("运营账户列表数据查询成功。", pageInfo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.errorMsg("哎呀,查询失败了。");
    }

    public List<KuaiShouOperateAccountVo> exportKuaiShouOperateAccountInfo(String startTime, String endTime, String projectId, String userId) {
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");
        try {
            //查询当前人员所有下级
            Set<String> operatorUserIds = getAffiliateId(userId);
            //2022-02-15 ==>> 20220215
            long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
            long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));

            //计算环比 时间值 上阶段时间 以及 两个日期之间的 间隔天数
            Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
            long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
            long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));
            Integer daysBetween = Integer.valueOf(lastTime.get("daysBetween")) + 1;

            //计算同比 时间值 只支持7天
            long startEqually = new Long("0");
            long endEqually = new Long("0");
            if (daysBetween <= 7) {
                startEqually = DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(startTime)), -7));
                endEqually = DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(endTime)), -7));
            }

            //查询运营数据-账户 维度
            List<KuaiShouOperateAccountVo> listOperate = materialStareMapper.getKuaiShouOperateAccountInfo(startDate, entDate, projectId, null, operatorUserIds);
            for (KuaiShouOperateAccountVo accountInfo : listOperate) {

                //查询 有效 上新视频 爆款视频
                JSONObject newEffect = materialStareMapper.getKuaiShouAccountBaseByUserId(null, null, String.valueOf(accountInfo.getAccountId()), startDate, entDate);
                accountInfo.setNewEffectNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newEffectNum"));//有效
                accountInfo.setNewVideoNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newVideoNum"));//上新
                accountInfo.setNewHotNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newHotNum"));//爆款

                long accountId = accountInfo.getAccountId();
                List<KuaiShouOperateAccountVo> accountYearOnYearInfo = materialStareMapper.getKuaiShouOperateAccountInfo(lastTimeStart, lastTimeEnd, projectId, accountId, operatorUserIds);
                //环比 = （当前 - 上阶段 ） / 上阶段
                String yearOnYear = "0";
                if (!Check.isNull(accountYearOnYearInfo)) {
                    Double yearOnYearD = (accountInfo.getTotalCost() - accountYearOnYearInfo.get(0).getTotalCost()) / accountYearOnYearInfo.get(0).getTotalCost();
                    yearOnYear = decimalFormat.format(yearOnYearD);
                }
                accountInfo.setYearOnYear(yearOnYear);

                //同比 日期超过 7 天 则不显示
                String equallyRate = "-";
                if (daysBetween <= 7) {
                    List<KuaiShouOperateAccountVo> accountEquallyInfo = materialStareMapper.getKuaiShouOperateAccountInfo(startEqually, endEqually, projectId, accountId, operatorUserIds);
                    if (!Check.isNull(accountEquallyInfo)) {
                        Double equallyRateD = (accountInfo.getTotalCost() - accountEquallyInfo.get(0).getTotalCost()) / accountEquallyInfo.get(0).getTotalCost();
                        equallyRate = decimalFormat.format(equallyRateD);
                    }
                }
                accountInfo.setEquallyRate(equallyRate);
            }

            return listOperate;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * @param accountId
     * @description: 查询账户余额 以及 账户状态 和 消耗
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/2/21
     */
    @Override
    public Result getKuaiShouAccountInfo(long accountId) {
        Map resultMap = new HashMap();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        // ==>> 20220202
        String now = sdf.format(new Date());
        long nowDate = Long.valueOf(now);
        //当前月份第一天
        long monthFirstDay = Long.valueOf(DateUtils.getFirstDayByMonth());
        //账户余额
        JSONObject balance = materialStareMapper.getKuaiShouAccountBalance(accountId);
        resultMap.put("balance", Check.isNull(balance) ? "0" : balance.getString("balance"));
        //账户今日消耗 以及状态
        JSONObject totalCost = materialStareMapper.getKuaiShouAccountTotalCost(accountId, nowDate);

        resultMap.put("accountId", Check.isNull(totalCost) ? "-" : totalCost.getString("accountId"));
        resultMap.put("accountName", Check.isNull(totalCost) ? "0" : totalCost.getString("accountName"));

        resultMap.put("totalCost", Check.isNull(totalCost) ? "0" : totalCost.getString("todayCost"));
        //0-开 1-关
        resultMap.put("state", Check.isNull(totalCost) ? "1" : totalCost.getString("accountStatus"));

        return Result.successMsg("账户查询成功", resultMap);
    }


    /**
     * @param accountId
     * @param startTime
     * @param endTime
     * @description: 账户 折线图 查询时间为当天查询时报；查询时间为多天 查询日报
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/2/21
     */
    @Override
    public Result getKuaiShouAccountInfoBrokenLine(long accountId, String startTime, String endTime, String type) {

        List<JSONObject> resultList = new ArrayList<>();
        try {
            //2022-02-15 ==>> 20220215
            long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
            long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));

            //两个日期之间的 间隔天数
            Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
            Integer daysBetween = Integer.valueOf(lastTime.get("daysBetween"));

            if (daysBetween == 0) {
                //昨天
                long yesterday = DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(entDate), -1));
                resultList = materialStareMapper.getKuaiShouAccountInfoBrokenLineHour(type, accountId, startDate, yesterday);
                return Result.successMsg("账户时报报折线图查询成功", resultList);
            }
            resultList = materialStareMapper.getKuaiShouAccountInfoBrokenLineDaily(type, accountId, startDate, entDate);

            return Result.successMsg("账户日报折线图查询成功", resultList);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.errorMsg("账户折线图查询异常");
    }


    /**
     * @param accountId
     * @param searchType searchType：查询类型  0-全部 1-上新 2-有效 3-爆款
     * @param startTime
     * @param endTime
     * @description: 快手 账户 素材上新-有效-爆款
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/2/21
     */
    @Override
    public Result getKuaiShouAccountMaterialNewAndEffectAndFaddish(long accountId, String searchType, String startTime, String endTime, Integer pageNum, Integer pageSize) {
        //2022-02-15 ==>> 20220215
        long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
        long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));
        PageHelper.startPage(pageNum, pageSize);
        List<JSONObject> resultList = materialStareMapper.getKuaiShouAccountMaterialNewAndEffectAndFaddish(accountId, searchType, startDate, entDate);
        PageInfo<JSONObject> pageInfo = new PageInfo<>(resultList);
        return Result.successMsg("查询账户素材信息成功。", pageInfo);
    }

    /**
     * @param accountId
     * @param startTime
     * @param endTime
     * @description: 查询账户饼图数据信息
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/2/22
     */
    @Override
    public Result getKuaiShouAccountPieChar(long accountId, String startTime, String endTime, String type) {
        Map resultMap = new HashMap();
        //2022-02-15 ==>> 20220215
        long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
        long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));
        //版位
        List<KuaiShouAccountPieVo> sceneList = materialStareMapper.getKuaiShouAccountPieScene(accountId, startDate, entDate, type);
        //年龄
        List<KuaiShouAccountPieVo> ageList = materialStareMapper.getKuaiShouAccountPieAge(accountId, startDate, entDate, type);
        //性别
        List<KuaiShouAccountPieVo> genderList = materialStareMapper.getKuaiShouAccountPieGender(accountId, startDate, entDate, type);
        resultMap.put("scene", sceneList);
        resultMap.put("age", ageList);
        resultMap.put("gender", genderList);
        return Result.successMsg("查询饼图数据成功。", resultMap);
    }

    @Override
    public Result kuaiShouRealTimeUnitDateInfo(long accountId, Integer pageNum, Integer pageSize) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        // ==>> 20220202
        String now = sdf.format(new Date());
        long nowDate = Long.valueOf(now);

        PageHelper.startPage(pageNum, pageSize);
        List<JSONObject> ListUnit = materialStareMapper.kuaiShouRealTimeUnitDateInfo(accountId, nowDate);
        for (JSONObject unitVo : ListUnit) {

            //优化目标
            Integer conver = Check.isNull(unitVo.getInteger("ocpx_action_type")) ? 0 : unitVo.getInteger("ocpx_action_type");

            //优化目标： 激活，  付费，  行为，  表单提交，  注册，  唤起应用，  关键行为
            //对应转化数 激活数，付费数，行为数，表单提交数，注册数，唤起应用次数，关键行为数
            //优化目标id 来源---ctop_kuaishou_ocpx_action_type_config
            unitVo.put("converNum", 0);//默认
            //激活
            if (conver == 180) {
                unitVo.put("converNum", unitVo.getInteger("activation"));
            }
            //付费
            if (conver == 190) {
                unitVo.put("converNum", unitVo.getInteger("eventPay"));
            }
            //行为
            if (conver == 2) {
                unitVo.put("converNum", unitVo.getInteger("bClick"));
            }
            //表单提交
            if (conver == 53) {
                unitVo.put("converNum", unitVo.getInteger("formCount"));
            }
            //注册
            if (conver == 396) {
                unitVo.put("converNum", unitVo.getInteger("eventRegister"));
            }
            //唤起应用
            if (conver == 324) {
                unitVo.put("converNum", unitVo.getInteger("eventAppInvoked"));
            }
            //关键行为
            if (conver == 773) {
                unitVo.put("converNum", unitVo.getInteger("keyAction"));
            }

            //转化成本 = 花费 / 转化数
            double converCost = unitVo.getInteger("converNum") == 0 ? 0 : unitVo.getDouble("charge") / unitVo.getInteger("converNum");
            unitVo.put("converCost", converCost);


            //操作建议

            //消耗
            Double charge = unitVo.getDoubleValue("charge");

            //出价 单位:厘
            long bid = new Long("1000");
            //2：CPC
            if (unitVo.getInteger("bidType") == 2) {
                bid = unitVo.getLong("bid");
                //10：OCPM
            } else if (unitVo.getInteger("bidType") == 10) {
                bid = unitVo.getLong("cpaBid");
            }
            Double price = new Double(bid / 1000).doubleValue();

            //转化数量
            Integer converNum = unitVo.getInteger("converNum");

            unitVo.put("operationAgree", "暂无");
            unitVo.put("operationContent", "暂无");
            unitVo.put("operationAgreeInfo", "暂无");

            //1. 转化成本大于出价×120%，消耗大于500元：
            if ((converCost > price * 1.2) && (charge > 500)) {
                unitVo.put("operationAgree", "高成本 | 有消耗");
                unitVo.put("operationContent", "建议限制预算");
                unitVo.put("operationAgreeInfo", "当前广告组转化成本偏高且消耗大于500，建议限制预算;");
            }
            //2.  转化成本大于出价×120%，转化数大于10小于等于50：
            if (converCost > price * 1.2 && LinkUtil.isInTheInterval(String.valueOf(converNum), "(10,50)")) {

                unitVo.put("operationAgree", "高成本 | 有转化");
                unitVo.put("operationContent", "建议限制预算");
                unitVo.put("operationAgreeInfo", "当前广告组成本大于出价×120%且转化数介于10-50之间;");
            }
            //3. 转化成本大于出价×120%，转化数大于50
            if (converCost > price * 1.2 && LinkUtil.isInTheInterval(String.valueOf(converNum), "(50,∞)")) {
                unitVo.put("operationAgree", "高成本 | 有转化");
                unitVo.put("operationContent", "建议降低出价");
                unitVo.put("operationAgreeInfo", "当前转化成本大于出价×120%，转化数大于50，建议降低出价;");
            }
            //4.  转化成本小于等于出价×120%，转化数大于10小于等于50
            if (converCost <= price * 1.2 && LinkUtil.isInTheInterval(String.valueOf(converNum), "(10,50]")) {
                unitVo.put("operationAgree", "成本合理 | 有转化");
                unitVo.put("operationContent", "建议复制推广组或放开预算");
                unitVo.put("operationAgreeInfo", "当前转化成本小于等于出价×120%，转化数大于10小于等于50，建议复制推广组或放开预算;");
            }
            //5.  消耗大于0小于等于100，转化数大于0小于等于10：
            if (LinkUtil.isInTheInterval(String.valueOf(charge), "(0,100]") && LinkUtil.isInTheInterval(String.valueOf(converNum), "(0,10]")) {
                unitVo.put("operationAgree", "消耗少 | 转化少");
                unitVo.put("operationContent", "建议启用加速探索");
                unitVo.put("operationAgreeInfo", "当前广告组消耗大于0小于等于100，转化数大于0小于等于10，建议加速探索;");
            }
            //6.  消耗大于等于500，转化数等于0：
            if (charge >= 500 && converNum == 0) {
                unitVo.put("operationAgree", "有消耗 | 无转化");
                unitVo.put("operationContent", "建议暂停广告组");
                unitVo.put("operationAgreeInfo", "当前广告组消耗大于等于500且转化数等于0，建议暂停推广组;");
            }
            //7.   消耗大于100小于等于500
            if (LinkUtil.isInTheInterval(String.valueOf(charge), "(100,500]")) {
                unitVo.put("operationAgree", "有一定消耗");
                unitVo.put("operationContent", "建议继续观察");
                unitVo.put("operationAgreeInfo", "当前广告组消耗大于100小于等于500，建议继续观察;");
            }
        }


        PageInfo<JSONObject> pageInfo = new PageInfo<>(ListUnit);
        return Result.successMsg("查询快手组当天实时数据成功。", pageInfo);

    }


    /**
     * @param startTime
     * @param endTime
     * @param pageNum
     * @param pageSize
     * @description: 运营组列表数据
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/8/31 15:16
     */
    @Override
    public Result getOperationGroupData(String userId, String mediaType, String startTime, String endTime, Integer pageNum, Integer pageSize) {
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");
        try {

            long nowDate = Long.valueOf(DateUtils.getDateInteger(DateUtils.getDate("yyyy-MM-dd")));

            long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));

            long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));
            boolean currentDayOnly = isCurrentDayOnly(startDate, entDate, nowDate);

            //计算环比 时间值 上阶段时间 以及 两个日期之间的 间隔天数
            Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
            long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
            long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));
            Integer daysBetween = Integer.valueOf(lastTime.get("daysBetween")) + 1;

            //查询用户角色
            String roleCode = materialStareMapper.getRoleCodeByUserId(userId);

            //所有运营经理 1-头条 2-快手
            String roleCodeName = "";
            List<KuaiShouOperateGroupVo> allOperationManagerList;
            if (mediaType.equals("1")) {
                roleCodeName = "touTiaoOperationManager";
                allOperationManagerList = dashboardQuerySupport.getOperationManagers(roleCodeName);
            } else if (mediaType.equals("16")) {
                allOperationManagerList = dashboardQuerySupport.getTencentOperationManagers();
            } else {
                roleCodeName = "kuaishouOperationManager";
                allOperationManagerList = dashboardQuerySupport.getOperationManagers(roleCodeName);
            }
            List<String> allManagerList = allOperationManagerList.stream().map(KuaiShouOperateGroupVo::getUserId).collect(Collectors.toList());

            List<KuaiShouOperateGroupVo> operationManagerList = new ArrayList<>();
            if ("admin".equals(roleCode)) {
                //所有运营经理
                operationManagerList = allOperationManagerList;
            } else if (roleCode.contains("OperationManager")) {
                // 如果下级有 运营经理 也需要分组展示
                // 获取下级中 角色为 运营经理人员
                //获取所有下级
                Set<String> userIds = getAffiliateId(userId);
                for (String uId : userIds) {
                    if (allManagerList.contains(uId)) {
                        JSONObject userName = materialStareMapper.getKuaiShouUserByUserId(uId);
                        operationManagerList.add(new KuaiShouOperateGroupVo(uId, userName.getString("userName")));
                    }
                }

            } else {
                Result.successMsg("运营组列表数据查询成功。", null);
            }

            List<KuaiShouOperateGroupVo> operationList = ListPageUtil.page(operationManagerList, pageSize, pageNum);
            Map<String, Set<String>> affiliateMap = new HashMap<>();
            List<String> managerIds = operationList.stream().map(KuaiShouOperateGroupVo::getUserId).collect(Collectors.toList());
            Map<String, Integer> subordinateCountMap = toCountMap(materialStareMapper.getOperateSubordinateCountBatch(managerIds), "managerId", "subordinateCount");
            Map<String, Set<String>> activeTeamMemberMap = dashboardQuerySupport.getOperateTeamMembers(mediaType, managerIds, startDate, entDate);
            Set<String> allActiveUserIds = new HashSet<>();
            for (Set<String> memberIds : activeTeamMemberMap.values()) {
                if (memberIds != null) {
                    allActiveUserIds.addAll(memberIds);
                }
            }
            Map<String, KuaiShouOperateVo> currentOperateMap = toOperateUserMap(loadOperateDataByMedia(mediaType, daysBetween, startDate, entDate, allActiveUserIds));
            Map<String, KuaiShouOperateVo> yearOnYearOperateMap = toOperateUserMap(loadOperateDataByMedia(mediaType, daysBetween, lastTimeStart, lastTimeEnd, allActiveUserIds));
            Map<String, JSONObject> historyBaseMap = loadUserBaseMapByMedia(mediaType, allActiveUserIds, startDate, entDate);
            Map<String, JSONObject> todayBaseMap = currentDayOnly ? loadTodayUserBaseMapByMedia(mediaType, allActiveUserIds, nowDate) : new HashMap<>();
            for (KuaiShouOperateGroupVo groupVo : operationList) {
                //下级员工
                Set<String> allAffiliateUserIds = affiliateMap.computeIfAbsent(groupVo.getUserId(), this::getAffiliateId);
                Set<String> operatorUserIds = activeTeamMemberMap.get(groupVo.getUserId());

                if (Check.isNull(operatorUserIds) || operatorUserIds.size() < 1) {
                    continue;
                }

                //运营数量
                int operationNum = subordinateCountMap.containsKey(groupVo.getUserId())
                        ? subordinateCountMap.get(groupVo.getUserId()) + 1
                        : (Check.isNull(allAffiliateUserIds) ? 0 : allAffiliateUserIds.size());
                groupVo.setOperationNum(operationNum);

                List<KuaiShouOperateVo> listOperate = mapOperateData(operatorUserIds, currentOperateMap);


                //总花费
                Double totalCost = Check.isNull(listOperate) ? 0 : listOperate.stream().mapToDouble(KuaiShouOperateVo::getTotalCost).sum();
                groupVo.setTotalCost(new BigDecimal(totalCost).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());

                //日均消耗 总花费/天数
                Double aveDay = daysBetween == 0 ? 0 : totalCost / daysBetween;
                groupVo.setAverageDayCost(new BigDecimal(aveDay).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());
                //人均消耗
                Double avePeople = aveDay == 0 ? 0 : aveDay / operationNum;
                groupVo.setAveragePeopleCost(new BigDecimal(avePeople).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());

                //项目数量
                Double projectNum = Check.isNull(listOperate) ? 0 : listOperate.stream().mapToDouble(KuaiShouOperateVo::getProjectNum).sum();
                groupVo.setProjectNum(projectNum.longValue());
                //账户数量
                Double accountNum = Check.isNull(listOperate) ? 0 : listOperate.stream().mapToDouble(KuaiShouOperateVo::getAccountNum).sum();
                groupVo.setAccountNum(accountNum.longValue());
                //平均账户消耗 总花费/账户数量
                Double aveAccount = accountNum.intValue() == 0 ? 0 : totalCost / accountNum;
                groupVo.setAverageAccountCost(new BigDecimal(aveAccount).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());

                //环比 = （当前 - 上阶段 ） / 上阶段
                List<KuaiShouOperateVo> yearOnYearInfo = mapOperateData(operatorUserIds, yearOnYearOperateMap);
                Double lastTotalCost = Check.isNull(yearOnYearInfo) ? 0 : yearOnYearInfo.stream().mapToDouble(KuaiShouOperateVo::getTotalCost).sum();
                String yearOnYear = formatRate(totalCost, lastTotalCost, decimalFormat);
                //花费环比
                groupVo.setYearOnYearCost(yearOnYear);

                if (mediaType.equals("1")) {
                    groupVo.setNewProjectNum(sumJsonInt(operatorUserIds, historyBaseMap, "newCpdProjectNum"));
                }
                if (!mediaType.equals("16")) {
                    int historyUnitNum = mediaType.equals("1")
                            ? sumJsonInt(operatorUserIds, historyBaseMap, "newUnitNum", "newUnitNum2")
                            : sumJsonInt(operatorUserIds, historyBaseMap, "newUnitNum");
                    int todayUnitNum = mediaType.equals("2") ? sumJsonInt(operatorUserIds, todayBaseMap, "newUnitNum") : 0;
                    groupVo.setUnitNum(historyUnitNum + todayUnitNum);
                }
            }
            PageInfo<KuaiShouOperateGroupVo> pageInfo = new PageInfo<>(operationList);
            pageInfo.setTotal(operationManagerList.size());
            pageInfo.setPageSize(pageSize);
            pageInfo.setPageNum(pageNum);
            pageInfo.setIsLastPage(false);
            pageInfo.setHasNextPage(true);
            return Result.successMsg("运营组列表数据查询成功。", pageInfo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.errorMsg("哎呀,查询失败了。");
    }


    public Result exportOperationGroupData(String userId, String mediaType, String startTime, String endTime, HttpServletResponse response) {
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");
        try {
            long nowDate = Long.valueOf(DateUtils.getDateInteger(DateUtils.getDate("yyyy-MM-dd")));

            long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
            long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));
            boolean currentDayOnly = isCurrentDayOnly(startDate, entDate, nowDate);
            //计算环比 时间值 上阶段时间 以及 两个日期之间的 间隔天数
            Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
            long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
            long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));
            Integer daysBetween = Integer.valueOf(lastTime.get("daysBetween")) + 1;
            //查询用户角色
            String roleCode = materialStareMapper.getRoleCodeByUserId(userId);

            //所有运营经理 1-头条 2-快手 16-腾讯
            List<KuaiShouOperateGroupVo> allOperationManagerList;
            String roleCodeName = "";
            if (mediaType.equals("1")) {
                roleCodeName = "touTiaoOperationManager";
                allOperationManagerList = materialStareMapper.getOperationManagerUser(roleCodeName);
            } else if (mediaType.equals("16")) {
                allOperationManagerList = dashboardQuerySupport.getTencentOperationManagers();
            } else {
                roleCodeName = "kuaishouOperationManager";
                allOperationManagerList = materialStareMapper.getOperationManagerUser(roleCodeName);
            }
            List<String> allManagerList = allOperationManagerList.stream().map(KuaiShouOperateGroupVo::getUserId).collect(Collectors.toList());

            List<KuaiShouOperateGroupVo> operationManagerList = new ArrayList<>();
            if ("admin".equals(roleCode)) {
                //所有运营经理
                operationManagerList = allOperationManagerList;
            } else if (roleCode.contains("OperationManager")) {
                // 如果下级有 运营经理 也需要分组展示
                // 获取下级中 角色为 运营经理人员
                //获取所有下级
                Set<String> userIds = getAffiliateId(userId);
                for (String uId : userIds) {
                    if (allManagerList.contains(uId)) {
                        JSONObject userName = materialStareMapper.getKuaiShouUserByUserId(uId);
                        operationManagerList.add(new KuaiShouOperateGroupVo(uId, userName.getString("userName")));
                    }
                }

            } else {
                Result.successMsg("运营组列表数据查询成功。", null);
            }

            List<String> managerIds = operationManagerList.stream().map(KuaiShouOperateGroupVo::getUserId).collect(Collectors.toList());
            Map<String, Set<String>> activeTeamMemberMap = mediaType.equals("16")
                    ? dashboardQuerySupport.getOperateTeamMembers(mediaType, managerIds, startDate, entDate)
                    : new HashMap<>();

            for (KuaiShouOperateGroupVo groupVo : operationManagerList) {
                //下级员工
                //Set<String> operatorUserIds = getAffiliateId(groupVo.getUserId());

                //运营经理下的下级员工
                Set<String> operatorUserIds = mediaType.equals("16")
                        ? activeTeamMemberMap.get(groupVo.getUserId())
                        : materialStareMapper.getAllOperatorsByLearderId(groupVo.getUserId());


                //有消耗的账户
                if (mediaType.equals("1")) {
                    operatorUserIds = materialStareMapper.getBytedanceAllOperators(null, DateUtils.getDateInteger(startTime).longValue(), DateUtils.getDateInteger(endTime).longValue(), operatorUserIds);
                } else if (mediaType.equals("2")) {
                    operatorUserIds = materialStareMapper.getKuaiShouAllOperators(null, DateUtils.getDateInteger(startTime).longValue(), DateUtils.getDateInteger(endTime).longValue(), operatorUserIds);
                }


                if (Check.isNull(operatorUserIds) || operatorUserIds.size() < 1) {
                    continue;
                }

                //运营数量
                int operationNum = Check.isNull(getAffiliateId(groupVo.getUserId())) ? 0 : getAffiliateId(groupVo.getUserId()).size();
                groupVo.setOperationNum(operationNum);

                //查询账户数据
                List<KuaiShouOperateVo> listOperate = new ArrayList<>();

                if (mediaType.equals("1")) {
                    if (currentDayOnly) {
                        //时报
                        listOperate = materialStareMapper.getBytedanceOperateInfoHourly(startDate, entDate, getCurrentHourSafe(), operatorUserIds);
                    } else {

                        listOperate = materialStareMapper.getBytedanceOperateInfo(startDate, entDate, operatorUserIds);
                    }
                } else if (mediaType.equals("16")) {
                    if (currentDayOnly) {
                        listOperate = materialStareMapper.getAdqOperateInfoHourly(startDate, entDate, getCurrentHourSafe(), operatorUserIds);
                    } else {
                        listOperate = materialStareMapper.getAdqOperateInfo(startDate, entDate, operatorUserIds);
                    }
                } else {
                    if (currentDayOnly) {
                        listOperate = materialStareMapper.getKuaiShouOperateInfoHourly(startDate, entDate, getCurrentHourSafe(), operatorUserIds);
                    } else {
                        listOperate = materialStareMapper.getKuaiShouOperateInfo(startDate, entDate, operatorUserIds);
                    }
                }

                //总花费
                Double totalCost = Check.isNull(listOperate) ? 0 : listOperate.stream().mapToDouble(KuaiShouOperateVo::getTotalCost).sum();
                groupVo.setTotalCost(new BigDecimal(totalCost).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());

                //日均消耗 总花费/天数
                Double aveDay = daysBetween == 0 ? 0 : totalCost / daysBetween;
                groupVo.setAverageDayCost(new BigDecimal(aveDay).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());
                //人均消耗
                Double avePeople = aveDay == 0 ? 0 : aveDay / operationNum;
                groupVo.setAveragePeopleCost(new BigDecimal(avePeople).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());

                //项目数量
                Double projectNum = Check.isNull(listOperate) ? 0 : listOperate.stream().mapToDouble(KuaiShouOperateVo::getProjectNum).sum();
                groupVo.setProjectNum(projectNum.longValue());
                //账户数量
                Double accountNum = Check.isNull(listOperate) ? 0 : listOperate.stream().mapToDouble(KuaiShouOperateVo::getAccountNum).sum();
                groupVo.setAccountNum(accountNum.longValue());
                //平均账户消耗 总花费/账户数量
                Double aveAccount = accountNum.intValue() == 0 ? 0 : totalCost / accountNum;
                groupVo.setAverageAccountCost(new BigDecimal(aveAccount).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());

                //环比 = （当前 - 上阶段 ） / 上阶段
                List<KuaiShouOperateVo> yearOnYearInfo = new ArrayList<>();
                if (mediaType.equals("1")) {
                    yearOnYearInfo = materialStareMapper.getBytedanceOperateInfo(lastTimeStart, lastTimeEnd, operatorUserIds);
                } else if (mediaType.equals("16")) {
                    yearOnYearInfo = materialStareMapper.getAdqOperateInfo(lastTimeStart, lastTimeEnd, operatorUserIds);
                } else {
                    yearOnYearInfo = materialStareMapper.getKuaiShouOperateInfo(lastTimeStart, lastTimeEnd, operatorUserIds);
                }
                String yearOnYear = "0";
                if (!Check.isNull(yearOnYearInfo)) {
                    Double lastTotalCost = Check.isNull(yearOnYearInfo) ? 0 : yearOnYearInfo.stream().mapToDouble(KuaiShouOperateVo::getTotalCost).sum();
                    Double yearOnYearD = (totalCost - lastTotalCost) / lastTotalCost;
                    yearOnYear = decimalFormat.format(yearOnYearD);
                }
                //花费环比
                groupVo.setYearOnYearCost(yearOnYear);

                //当天
                int newUnitNumNow = 0;
                if (currentDayOnly) {
                    JSONObject newEffect = new JSONObject();
                    if (mediaType.equals("1")) {
                        //查询 当天有效 上新计划 上新组
                        newEffect = materialStareMapper.getBytedanceAccountBaseByUserId(operatorUserIds, null, null, nowDate, nowDate);
                        Integer unitNum = Check.isNull(newEffect) ? 0 : newEffect.getInteger("newUnitNum");//组
                        Integer unitNum1 = Check.isNull(newEffect) ? 0 : newEffect.getInteger("newUnitNum2");//组
                        newUnitNumNow = Math.addExact(unitNum, unitNum1);
                    } else if (mediaType.equals("2")) {
                        //查询 当天有效 上新计划 上新组
                        newEffect = materialStareMapper.getKuaiShouAccountNowBaseByUserId(operatorUserIds, null, null, nowDate, nowDate);
                        newUnitNumNow = Check.isNull(newEffect) ? 0 : newEffect.getInteger("newUnitNum");//组
                    }
                }

                if (mediaType.equals("1")) {
                    JSONObject newEffect = materialStareMapper.getBytedanceAccountBaseByUserId(operatorUserIds, null, null, startDate, entDate);
                    Integer unitNum = Check.isNull(newEffect) ? 0 : newEffect.getInteger("newUnitNum");//组
                    Integer unitNum1 = Check.isNull(newEffect) ? 0 : newEffect.getInteger("newUnitNum2");//组
                    newUnitNumNow = Math.addExact(unitNum, unitNum1);
                    groupVo.setNewProjectNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newCpdProjectNum"));
                } else if (mediaType.equals("2")) {
                    //查询 历史上新组
                    JSONObject newEffect = materialStareMapper.getKuaiShouAccountBaseByUserId(operatorUserIds, null, null, startDate, entDate);
                    newUnitNumNow = Check.isNull(newEffect) ? 0 : newEffect.getInteger("newUnitNum") + newUnitNumNow;
                }

                //基建数量
                groupVo.setUnitNum(newUnitNumNow);//组
            }

            Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("运营组数据详情", "运营组数据"), KuaiShouOperateGroupVo.class, operationManagerList);
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("运营组数据详情.xlsx", "UTF-8"));
            workbook.write(response.getOutputStream());
            return null;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.errorMsg("哎呀,查询失败了。");
    }

    @Override
    public List<KuaiShouOperateProjectVo> getOperateProjectInfo(Integer pageNum, int pageSize, String mediaType, String startTime, String endTime, String userId) throws ParseException {
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");
        long now = Long.valueOf(DateUtils.getDateInteger(DateUtils.getDate("yyyy-MM-dd")));
        List<KuaiShouOperateProjectVo> listOperate = new ArrayList<>();
        //查询当前人员所有下级
        Set<String> operatorUserIds = getAffiliateId(userId);
        //2022-02-15 ==>> 20220215
        long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
        long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));

        //计算环比 时间值 上阶段时间 以及 两个日期之间的 间隔天数
        Map<String, String> lastTime = DateUtils.getStartEndTime(startTime, endTime);
        long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
        long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));
        Integer daysBetween = Integer.valueOf(lastTime.get("daysBetween")) + 1;

        Map<String, Object> parameterMap = new HashMap<>();
        parameterMap.put("startDate", startDate);
        parameterMap.put("endDate", entDate);
        parameterMap.put("lastTimeStart", lastTimeStart);
        parameterMap.put("lastTimeEnd", lastTimeEnd);
        parameterMap.put("userIds", operatorUserIds);
        parameterMap.put("startEqually", DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(startTime)), -7)));
        parameterMap.put("endEqually", DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(endTime)), -7)));
        boolean currentDayOnly = isCurrentDayOnly(startDate, entDate, now);
        if (mediaType.equals("1")) {
            if (currentDayOnly) {
                parameterMap.put("tableName", "application.bytedance_advertiser_report_hourly_dw");
                parameterMap.put("hour", DateUtils.getNowHour());
            } else {
                parameterMap.put("tableName", "application.bytedance_advertiser_report_daily_dw");
                parameterMap.remove("hour");
            }
        }
        if (mediaType.equals("2")) {
            if (currentDayOnly) {
                parameterMap.put("tableName", "application.kuaishou_account_report_hourly_dw");
                parameterMap.put("hour", DateUtils.getNowHour());
            } else {
                parameterMap.put("tableName", "application.kuaishou_account_report_daily_dw");
                parameterMap.remove("hour");
            }
        }

        //头条
        if (mediaType.equals("1")) {
            List<Long> projectIds = materialStareMapper.getBytedanceProjectList(parameterMap);
            if (Check.isNull(projectIds)) {
                return listOperate;
            }
            parameterMap.put("projectIds", projectIds);
            PageHelper.startPage(pageNum, pageSize);
            listOperate = materialStareMapper.getBytedanceOperateProjectInfoNew(parameterMap);
        }
        //快手
        if (mediaType.equals("2")) {
            List<Long> projectIds = materialStareMapper.getKuaishouProjectList(parameterMap);
            if (Check.isNull(projectIds)) {
                return listOperate;
            }
            parameterMap.put("projectIds", projectIds);
            PageHelper.startPage(pageNum, pageSize);
            listOperate = materialStareMapper.getKuaiShouOperateProjectInfoNew(parameterMap);
            for (KuaiShouOperateProjectVo vo : listOperate) {
                List<JSONObject> adSceneDate = JSONObject.parseArray(vo.getAdSceneDateStr(), JSONObject.class);
                vo.setAdSceneDate(adSceneDate);
            }
        }
        //计算同比 时间值 只支持7天
        if (daysBetween > 7) {
            for (KuaiShouOperateProjectVo projectVo : listOperate) {
                projectVo.setEquallyRate("-");
            }
        }
        return listOperate;
    }

//===========================================查询下级员工========================

    public Result getCompanyAllSubordinateByUserId(String userId) {
        Set<String> operatorUserIds = getAffiliateId(userId);
        return Result.successMsg("查询该用户所有下级userId", operatorUserIds);
    }


    /**
     * 查询当前人员  所属公司 返回自己和下属id
     */
    public Set<String> getAffiliateId(String userId) {

        //查询用户所属公司
//        String companyId = materialStareMapper.getUserCompanyByUserId(userId);
        //查询用户角色
        String roleCode = materialStareMapper.getRoleCodeByUserId(userId);
        //管理员查询公司下所有用户
       /* if ("admin".equals(roleCode)) {
            return materialStareMapper.getCompanyAllUserId(companyId);
        }*/

        Set<String> result;
        //查询当前用户是否存在下级
        Set<String> subordinate = materialStareMapper.getAffiliateId(userId, null);
        if (subordinate.isEmpty()) {
            if ("admin".equals(roleCode)) {
                return materialStareMapper.getCompanyAllUserId(null);
            }
            subordinate.add(userId);
            return subordinate;
        } else {
            //获取其下组员
            result = materialStareMapper.getSaleDirctorItsTeamMember(userId);
            result.add(userId);
        }
        return result;
    }

    private double getJsonDouble(JSONObject jsonObject, String key) {
        if (jsonObject == null || key == null) {
            return 0D;
        }
        return jsonObject.getDoubleValue(key);
    }

    private int getJsonInt(JSONObject jsonObject, String key) {
        if (jsonObject == null || key == null) {
            return 0;
        }
        return jsonObject.getIntValue(key);
    }

    private double safeDivide(double numerator, int denominator) {
        if (denominator <= 0) {
            return 0D;
        }
        return numerator / denominator;
    }

    private int safeSize(Set<String> userIds) {
        return userIds == null ? 0 : userIds.size();
    }

    private Integer getCurrentHourSafe() {
        try {
            return DateUtils.getNowHour();
        } catch (ParseException e) {
            throw new RuntimeException("Failed to resolve current hour", e);
        }
    }

    @SuppressWarnings("unchecked")
    private void alignGroupSummaryWithGroupRows(Map resultMap, String userId, String mediaType, String startTime, String endTime) {
        if (resultMap == null || StringUtils.isBlank(userId) || StringUtils.isBlank(mediaType)) {
            return;
        }
        Result groupResult = getOperationGroupData(userId, mediaType, startTime, endTime, 1, 1000);
        if (groupResult == null || !groupResult.isSuccess() || groupResult.getResult() == null) {
            return;
        }
        Object rawPage = groupResult.getResult();
        if (!(rawPage instanceof PageInfo)) {
            return;
        }
        PageInfo<KuaiShouOperateGroupVo> pageInfo = (PageInfo<KuaiShouOperateGroupVo>) rawPage;
        List<KuaiShouOperateGroupVo> rows = pageInfo.getList();
        if (rows == null || rows.isEmpty()) {
            return;
        }
        double sectionCost = rows.stream().filter(row -> row != null).mapToDouble(KuaiShouOperateGroupVo::getTotalCost).sum();
        long totalOperationNum = rows.stream().filter(row -> row != null).mapToLong(KuaiShouOperateGroupVo::getOperationNum).sum();
        long totalProjectNum = rows.stream().filter(row -> row != null).mapToLong(KuaiShouOperateGroupVo::getProjectNum).sum();
        long totalAccountNum = rows.stream().filter(row -> row != null).mapToLong(KuaiShouOperateGroupVo::getAccountNum).sum();
        double averagePeopleCost = totalOperationNum <= 0 ? 0D : sectionCost / totalOperationNum;
        double averageAccountNum = totalOperationNum <= 0 ? 0D : (double) totalAccountNum / totalOperationNum;
        DecimalFormat df = new DecimalFormat("#.000");
        resultMap.put("sectionCost", new BigDecimal(sectionCost).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());
        resultMap.put("userAveragecost", averagePeopleCost == 0D ? 0 : df.format(averagePeopleCost));
        resultMap.put("userAverageAccount", (int) Math.ceil(averageAccountNum));
        resultMap.put("projectNum", String.valueOf(totalProjectNum));
        long startDate = DateUtils.getDateInteger(startTime);
        long endDate = DateUtils.getDateInteger(endTime);
        long nowDate = DateUtils.getDateInteger(DateUtils.getDate("yyyy-MM-dd"));
        if (startDate == endDate && startDate == nowDate) {
            resultMap.put("todayCost", new BigDecimal(sectionCost).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());
        }
    }

    private long buildAccountQueryStart(long startDate, long lastTimeStart, long startEqually, boolean includeEqually) {
        long queryStartDate = Math.min(startDate, lastTimeStart);
        if (includeEqually) {
            queryStartDate = Math.min(queryStartDate, startEqually);
        }
        return queryStartDate;
    }

    private String formatRate(double currentValue, double baseValue, DecimalFormat decimalFormat) {
        if (baseValue == 0D) {
            return decimalFormat.format(0D);
        }
        return decimalFormat.format((currentValue - baseValue) / baseValue);
    }

    private Map<Long, KuaiShouOperateAccountVo> toAccountVoMap(List<KuaiShouOperateAccountVo> accountRows) {
        Map<Long, KuaiShouOperateAccountVo> result = new LinkedHashMap<>();
        if (accountRows == null || accountRows.isEmpty()) {
            return result;
        }
        for (KuaiShouOperateAccountVo row : accountRows) {
            if (row == null) {
                continue;
            }
            result.put(row.getAccountId(), row);
        }
        return result;
    }

    private List<KuaiShouOperateAccountVo> sortAccountRowsByPageOrder(List<KuaiShouOperateAccountVo> accountRows, List<Long> orderedAccountIds) {
        if (accountRows == null || accountRows.isEmpty() || orderedAccountIds == null || orderedAccountIds.isEmpty()) {
            return accountRows == null ? new ArrayList<>() : accountRows;
        }
        Map<Long, KuaiShouOperateAccountVo> accountMap = toAccountVoMap(accountRows);
        List<KuaiShouOperateAccountVo> result = new ArrayList<>();
        for (Long accountId : orderedAccountIds) {
            KuaiShouOperateAccountVo accountVo = accountMap.get(accountId);
            if (accountVo != null) {
                result.add(accountVo);
            }
        }
        return result;
    }

    private List<KuaiShouOperateProjectVo> sortProjectRowsByPageOrder(List<KuaiShouOperateProjectVo> projectRows, List<Long> orderedProjectIds) {
        if (projectRows == null || projectRows.isEmpty() || orderedProjectIds == null || orderedProjectIds.isEmpty()) {
            return projectRows == null ? new ArrayList<>() : projectRows;
        }
        Map<Long, KuaiShouOperateProjectVo> projectMap = new LinkedHashMap<>();
        for (KuaiShouOperateProjectVo row : projectRows) {
            if (row == null || StringUtils.isBlank(row.getProjectId())) {
                continue;
            }
            projectMap.put(Long.valueOf(row.getProjectId()), row);
        }
        List<KuaiShouOperateProjectVo> result = new ArrayList<>();
        for (Long projectId : orderedProjectIds) {
            KuaiShouOperateProjectVo projectVo = projectMap.get(projectId);
            if (projectVo != null) {
                result.add(projectVo);
            }
        }
        return result;
    }

    private Map<Long, JSONObject> toAccountBaseMap(List<JSONObject> rows) {
        Map<Long, JSONObject> result = new LinkedHashMap<>();
        if (rows == null || rows.isEmpty()) {
            return result;
        }
        for (JSONObject row : rows) {
            if (row == null || row.getLong("accountId") == null) {
                continue;
            }
            result.put(row.getLong("accountId"), row);
        }
        return result;
    }

    private Map<String, JSONObject> toUserBaseMap(List<JSONObject> rows) {
        Map<String, JSONObject> result = new LinkedHashMap<>();
        if (rows == null || rows.isEmpty()) {
            return result;
        }
        for (JSONObject row : rows) {
            if (row == null || row.getString("userId") == null) {
                continue;
            }
            result.put(row.getString("userId"), row);
        }
        return result;
    }

    private Map<String, Integer> toCountMap(List<JSONObject> rows, String keyField, String valueField) {
        Map<String, Integer> result = new LinkedHashMap<>();
        if (rows == null || rows.isEmpty()) {
            return result;
        }
        for (JSONObject row : rows) {
            if (row == null || StringUtils.isBlank(row.getString(keyField))) {
                continue;
            }
            result.put(row.getString(keyField), row.getIntValue(valueField));
        }
        return result;
    }

    private int sumJsonInt(Set<String> userIds, Map<String, JSONObject> userBaseMap, String... keys) {
        if (userIds == null || userIds.isEmpty() || userBaseMap == null || userBaseMap.isEmpty() || keys == null || keys.length == 0) {
            return 0;
        }
        int total = 0;
        for (String userId : userIds) {
            JSONObject row = userBaseMap.get(userId);
            if (row == null) {
                continue;
            }
            for (String key : keys) {
                total += getJsonInt(row, key);
            }
        }
        return total;
    }

    private List<KuaiShouOperateVo> loadOperatePageData(String mediaType, long startDate, long endDate, long nowDate, Set<String> userIds) {
        boolean currentDayOnly = isCurrentDayOnly(startDate, endDate, nowDate);
        if ("1".equals(mediaType)) {
            if (currentDayOnly) {
                return materialStareMapper.getBytedanceOperateInfoHourly(nowDate, nowDate, getCurrentHourSafe(), userIds);
            }
            return materialStareMapper.getBytedanceOperateInfo(startDate, endDate, userIds);
        }
        if ("16".equals(mediaType)) {
            if (currentDayOnly) {
                return materialStareMapper.getAdqOperateInfoHourly(nowDate, nowDate, getCurrentHourSafe(), userIds);
            }
            return materialStareMapper.getAdqOperateInfo(startDate, endDate, userIds);
        }
        if (currentDayOnly) {
            return materialStareMapper.getKuaiShouOperateInfoHourly(nowDate, nowDate, getCurrentHourSafe(), userIds);
        }
        return materialStareMapper.getKuaiShouOperateInfo(startDate, endDate, userIds);
    }

    private void enrichOperateList(List<KuaiShouOperateVo> listOperate, String mediaType, long startDate, long endDate, long nowDate,
                                   long lastTimeStart, long lastTimeEnd, DecimalFormat decimalFormat) {
        if (listOperate == null || listOperate.isEmpty()) {
            return;
        }
        Set<String> userIds = listOperate.stream()
                .map(KuaiShouOperateVo::getUserId)
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.toSet());
        Map<String, KuaiShouOperateVo> yearOnYearMap = toOperateUserMap(loadOperatePageData(mediaType, lastTimeStart, lastTimeEnd, nowDate, userIds));
        Map<String, JSONObject> historyBaseMap = loadUserBaseMapByMedia(mediaType, userIds, startDate, endDate);
        boolean currentDayOnly = isCurrentDayOnly(startDate, endDate, nowDate);
        Map<String, JSONObject> todayBaseMap = currentDayOnly
                ? loadTodayUserBaseMapByMedia(mediaType, userIds, nowDate)
                : new HashMap<>();
        for (KuaiShouOperateVo operate : listOperate) {
            if (operate == null || StringUtils.isBlank(operate.getUserId())) {
                continue;
            }
            String currentUserId = operate.getUserId();
            JSONObject historyBase = historyBaseMap.get(currentUserId);
            JSONObject todayBase = todayBaseMap.get(currentUserId);
            if ("1".equals(mediaType)) {
                operate.setNewCampaignNum(getJsonInt(historyBase, "newCampaignNum"));
                operate.setNewUnitNum(getJsonInt(historyBase, "newUnitNum") + getJsonInt(historyBase, "newUnitNum2"));
                operate.setNewProjectNum(getJsonInt(historyBase, "newCpdProjectNum"));
            } else if ("2".equals(mediaType)) {
                operate.setNewCampaignNum(getJsonInt(historyBase, "newCampaignNum"));
                operate.setNewUnitNum(getJsonInt(historyBase, "newUnitNum") + getJsonInt(todayBase, "newUnitNum"));
            }
            KuaiShouOperateVo yearOnYearInfo = yearOnYearMap.get(currentUserId);
            operate.setRate(formatRate(operate.getTotalCost(), yearOnYearInfo == null ? 0D : yearOnYearInfo.getTotalCost(), decimalFormat));
        }
    }

    private Map<String, JSONObject> loadUserBaseMapByMedia(String mediaType, Set<String> userIds, long startDate, long endDate) {
        if (userIds == null || userIds.isEmpty()) {
            return new HashMap<>();
        }
        if ("1".equals(mediaType)) {
            return toUserBaseMap(materialStareMapper.getBytedanceAccountBaseGroupByUserIds(userIds, startDate, endDate));
        }
        if ("2".equals(mediaType)) {
            return toUserBaseMap(materialStareMapper.getKuaiShouAccountBaseGroupByUserIds(userIds, startDate, endDate));
        }
        return new HashMap<>();
    }

    private Map<String, JSONObject> loadTodayUserBaseMapByMedia(String mediaType, Set<String> userIds, long nowDate) {
        if (!"2".equals(mediaType) || userIds == null || userIds.isEmpty()) {
            return new HashMap<>();
        }
        return toUserBaseMap(materialStareMapper.getKuaiShouAccountNowBaseGroupByUserIds(userIds, nowDate, nowDate));
    }

    private List<KuaiShouOperateVo> loadOperateDataByMedia(String mediaType, Integer daysBetween, long startDate, long endDate, Set<String> userIds) {
        if (userIds == null || userIds.isEmpty()) {
            return new ArrayList<>();
        }
        long nowDate = DateUtils.getDateInteger(DateUtils.getDate("yyyy-MM-dd"));
        boolean currentDayOnly = isCurrentDayOnly(startDate, endDate, nowDate);
        if ("1".equals(mediaType)) {
            if (currentDayOnly) {
                return materialStareMapper.getBytedanceOperateInfoHourly(startDate, endDate, getCurrentHourSafe(), userIds);
            }
            return materialStareMapper.getBytedanceOperateInfo(startDate, endDate, userIds);
        }
        if ("16".equals(mediaType)) {
            if (currentDayOnly) {
                return materialStareMapper.getAdqOperateInfoHourly(startDate, endDate, getCurrentHourSafe(), userIds);
            }
            return materialStareMapper.getAdqOperateInfo(startDate, endDate, userIds);
        }
        if (currentDayOnly) {
            return materialStareMapper.getKuaiShouOperateInfoHourly(startDate, endDate, getCurrentHourSafe(), userIds);
        }
        return materialStareMapper.getKuaiShouOperateInfo(startDate, endDate, userIds);
    }

    private boolean isCurrentDayOnly(long startDate, long endDate, long nowDate) {
        return startDate == endDate && startDate == nowDate;
    }

    private Map<String, KuaiShouOperateVo> toOperateUserMap(List<KuaiShouOperateVo> rows) {
        Map<String, KuaiShouOperateVo> result = new LinkedHashMap<>();
        if (rows == null || rows.isEmpty()) {
            return result;
        }
        for (KuaiShouOperateVo row : rows) {
            if (row == null || row.getUserId() == null) {
                continue;
            }
            result.put(row.getUserId(), row);
        }
        return result;
    }

    private List<KuaiShouOperateVo> mapOperateData(Set<String> userIds, Map<String, KuaiShouOperateVo> operateMap) {
        List<KuaiShouOperateVo> result = new ArrayList<>();
        if (userIds == null || userIds.isEmpty() || operateMap == null || operateMap.isEmpty()) {
            return result;
        }
        for (String userId : userIds) {
            KuaiShouOperateVo operateVo = operateMap.get(userId);
            if (operateVo != null) {
                result.add(operateVo);
            }
        }
        return result;
    }

    //=========================查询下级的项目以及账户===============================================
    @Override
    public Result<List<JSONObject>> participateListByMediaIdAllSubordinate(JSONObject requestJson) {
        Result<List<JSONObject>> result = new Result<>();

        try {
            String userId = requestJson.getString("userId");
            if (Check.isNull(userId)) {
                throw new Exception("请选择userId");
            }

            //获取所有下级
            Set<String> userIds = getAffiliateId(userId);

            List<Integer> mediaIds = new ArrayList<>();
            String type = requestJson.getString("type");
            if (!Check.isNull(type)) {
                if ("kuaishou".equals(type)) {
                    mediaIds.add(2);
                    mediaIds.add(4);
                } else if ("bytedance".equals(type)) {
                    mediaIds.add(1);
                    mediaIds.add(3);
                }
            }
            //查询用户角色
            String roleCode = materialStareMapper.getRoleCodeByUserId(userId);
            //角色为 管理员 || 销售 || 媒介 查询全部
            if ("admin".equals(roleCode) || roleCode.contains("sale") || "meidaManager".equals(roleCode)) {
                userIds = null;
            }
            //查询项目信息以及广告主
            List<JSONObject> projectList = getProjectByUserIdAndMediaIdsSubordinate(userIds, mediaIds);
            List<JSONObject> haveList = new ArrayList<>();
            if (!Check.isNull(projectList)) {
                //项目id 查询账户人员信息
                Map<Long, List<JSONObject>> accountMap = getAccountListByProjectListSubordinate(userIds, projectList);
                for (int i = 0; i < projectList.size(); i++) {
                    JSONObject project = projectList.get(i);
                    if (!Check.isNull(project)) {
                        List<JSONObject> accountList = accountMap.get(project.getLong("projectId"));
                        if (!Check.isNull(accountList)) {
                            project.put("accountList", accountList);
                            haveList.add(project);
                        }
                    }
                }
            }
            result.setSuccess(true);
            result.setResult(haveList);
        } catch (Exception e) {
            e.printStackTrace();
            result.setSuccess(false);
            result.setMessage(e.getMessage());
        }
        return result;
    }

    public List<JSONObject> getProjectByUserIdAndMediaIdsSubordinate(Set<String> userIds, List<Integer> mediaIds) {
        return materialStareMapper.getProjectByUserIdAndMediaIdsSubordinate(userIds, mediaIds);
    }

    @Override
    public Map<Long, List<JSONObject>> getAccountListByProjectListSubordinate(Set<String> userIds, List<JSONObject> projectList) {
        Map<Long, List<JSONObject>> map = new HashMap<>();
        List list = new ArrayList();
        for (int i = 0; i < projectList.size(); i++) {
            JSONObject jsonObject = projectList.get(i);
            if (!Check.isNull(jsonObject)) {
                list.add(jsonObject.getLong("projectId"));
                map.put(jsonObject.getLong("projectId"), new ArrayList<>());
            }
        }
        List<JSONObject> jsonList = materialStareMapper.getAccountListByProjectListSubordinate(userIds, list);
        for (int i = 0; i < jsonList.size(); i++) {
            JSONObject jsonObject = jsonList.get(i);
            if (!Check.isNull(jsonObject)) {
                Long projectId = jsonObject.getLong("projectId");
                List<JSONObject> jsonObjects = map.get(projectId);
                jsonObjects.add(jsonObject);
            }
        }
        return map;
    }
    //=========================查询下级的项目以及账户===============================================


}
