package com.fs.statis.service.impl;

import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSONObject;
import com.fs.common.constant.FsConstants;
import com.fs.common.core.domain.R;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.TimeUtils;
import com.fs.common.utils.model.DateTimeEntity;
import com.fs.company.cache.ICompanyCacheService;
import com.fs.course.domain.FsCourseWatchLog;
import com.fs.course.dto.WatchLogDTO;
import com.fs.course.mapper.FsCourseTrafficLogMapper;
import com.fs.course.mapper.FsCourseWatchLogMapper;
import com.fs.his.service.IFsStoreOrderService;
import com.fs.his.service.IFsStorePaymentService;
import com.fs.his.service.IFsStoreProductService;
import com.fs.his.service.IFsUserService;
import com.fs.qw.domain.QwIpadServer;
import com.fs.qw.service.IQwIpadServerService;
import com.fs.statis.StatisticsRedisConstant;
import com.fs.statis.dto.*;
import com.fs.statis.mapper.ConsumptionBalanceMapper;
import com.fs.statis.param.WatchCourseStatisticsParam;
import com.fs.statis.service.IStatisticsService;
import com.fs.statis.service.utils.TrendDataFiller;

import com.fs.store.service.cache.IFsUserCourseCacheService;
import com.fs.system.domain.SysConfig;
import com.fs.system.service.ISysConfigService;
import com.hc.openapi.tool.fastjson.JSON;
import com.hc.openapi.tool.util.ObjectUtils;
import com.hc.openapi.tool.util.StringUtils;
import org.apache.http.util.Asserts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import com.fs.statistics.dto.WatchCourseStatisticsDTO;

import static com.fs.statis.StatisticsRedisConstant.*;

@Service("statisticsService")
public class StatisticsServiceImpl implements IStatisticsService {
    @Autowired
    private ConsumptionBalanceMapper consumptionBalanceMapper;

    @Autowired
    private IFsUserCourseCacheService fsUserCourseCacheService;

    @Autowired
    private ICompanyCacheService companyCacheService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private FsCourseTrafficLogMapper fsCourseTrafficLogMapper;
    @Autowired
    private IFsUserService userService;

    @Autowired
    private IFsStoreOrderService storeOrderService;

    @Autowired
    private IFsStorePaymentService paymentService;

    @Autowired
    private IFsStoreProductService productService;

    @Autowired
    private ISysConfigService configService;
    @Autowired
    private FsCourseWatchLogMapper fsCourseWatchLogMapper;

    @Autowired
    private IQwIpadServerService qwIpadServerService;



    @Override
    public void dataOverviewTask() {
        DealerAggregatedDTO dealerAggregatedDTO = this.dealerAggregated();
        ConsumptionBalanceDataDTO consumptionBalanceDataDTO = this.rechargeConsumption();
        AuthorizationInfoDTO authorizationInfoDTO = authorizationInfo();
        Long smsBalance = this.smsBalance();
        TrafficLogDTO trafficLog = this.getTrafficLog();

        redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AGGREGATED, dealerAggregatedDTO);
        redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_BALANCE, consumptionBalanceDataDTO);
        redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AUTHORIZATION_INFO, authorizationInfoDTO);
        redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_SMS_BALANCE, smsBalance);
        redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_TRAFFIC_LOG,trafficLog);
    }


    public void analysisPreviewTask0(){
        analysisPreviewTask(0,1);
        analysisPreviewTask(0,2);
    }

    public void analysisPreviewTask1(){
        analysisPreviewTask(0,1);
        analysisPreviewTask(1,1);
        analysisPreviewTask(2,1);
        analysisPreviewTask(3,1);
        analysisPreviewTask(4,1);

        analysisPreviewTask(0,2);
        analysisPreviewTask(1,2);
        analysisPreviewTask(2,2);
        analysisPreviewTask(3,2);
        analysisPreviewTask(4,2);
    }


    @Override
    public void analysisPreviewTask(Integer type,Integer userType) {
        // 根据type计算出时间范围
        String startDate = "";
        String endDate = "";

        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        LocalTime startOfDayTime = LocalTime.MIN;
        LocalTime endOfDayTime = LocalTime.of(23, 59, 59);

        if(0 == type){
            LocalDateTime startOfDay = now.with(startOfDayTime);
            LocalDateTime endOfDay = now.with(endOfDayTime);
            startDate = startOfDay.format(formatter);
            endDate = endOfDay.format(formatter);
        } else if(1 == type){
            LocalDateTime yesterday = now.minusDays(1);
            LocalDateTime startOfYesterday = yesterday.with(startOfDayTime);
            LocalDateTime endOfYesterday = yesterday.with(endOfDayTime);
            startDate = startOfYesterday.format(formatter);
            endDate = endOfYesterday.format(formatter);
        } else if(2 == type) {
            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
            LocalDateTime startOfStartOfWeek = startOfWeek.with(startOfDayTime);
            LocalDateTime endOfToday = now.with(endOfDayTime);
            startDate = startOfStartOfWeek.format(formatter);
            endDate = endOfToday.format(formatter);
        } else if(3 == type) {
            LocalDateTime startOfMonth = now.withDayOfMonth(1);
            LocalDateTime startOfStartOfMonth = startOfMonth.with(startOfDayTime);
            LocalDateTime endOfToday = now.with(endOfDayTime);
            startDate = startOfStartOfMonth.format(formatter);
            endDate = endOfToday.format(formatter);
        } else if(4 == type) {
            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);

            LocalDateTime startOfPrevMonthStart = firstDayOfPreviousMonth.with(startOfDayTime);
            LocalDateTime endOfPrevMonthEnd = lastDayOfPreviousMonth.with(endOfDayTime);

            startDate = startOfPrevMonthStart.format(formatter);
            endDate = endOfPrevMonthEnd.format(formatter);
        }

        AnalysisPreviewQueryDTO param = new AnalysisPreviewQueryDTO();
        param.setStartTime(startDate);
        param.setEndTime(endDate);
        param.setType(type);
        param.setUserType(userType);

        AnalysisPreviewDTO analysisPreviewDTO = this.analysisPreview(param);

        redisCache.setCacheObject(String.format("%s:%d:%d",DATA_OVERVIEW_DEALER_ANALYSISPREVIEW,type,userType), analysisPreviewDTO);
    }

    public void watchEndPlayTrendTask0(){
        this.watchEndPlayTrendTask(0,1);
        this.watchEndPlayTrendTask(0,2);
    }

    public void watchEndPlayTrendTask1(){
        this.watchEndPlayTrendTask(1,1);
        this.watchEndPlayTrendTask(2,1);
        this.watchEndPlayTrendTask(3,1);
        this.watchEndPlayTrendTask(4,1);

        this.watchEndPlayTrendTask(1,2);
        this.watchEndPlayTrendTask(2,2);
        this.watchEndPlayTrendTask(3,2);
        this.watchEndPlayTrendTask(4,2);
    }


    @Override
    public void watchEndPlayTrendTask(Integer type,Integer userType) {
        // 根据type计算出时间范围
        String startDate = "";
        String endDate = "";

        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        LocalTime startOfDayTime = LocalTime.MIN;
        LocalTime endOfDayTime = LocalTime.of(23, 59, 59);

        if(0 == type){
            LocalDateTime startOfDay = now.with(startOfDayTime);
            LocalDateTime endOfDay = now.with(endOfDayTime);
            startDate = startOfDay.format(formatter);
            endDate = endOfDay.format(formatter);
        } else if(1 == type){
            LocalDateTime yesterday = now.minusDays(1);
            LocalDateTime startOfYesterday = yesterday.with(startOfDayTime);
            LocalDateTime endOfYesterday = yesterday.with(endOfDayTime);
            startDate = startOfYesterday.format(formatter);
            endDate = endOfYesterday.format(formatter);
        } else if(2 == type) {
            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
            LocalDateTime startOfStartOfWeek = startOfWeek.with(startOfDayTime);
            LocalDateTime endOfToday = now.with(endOfDayTime);
            startDate = startOfStartOfWeek.format(formatter);
            endDate = endOfToday.format(formatter);
        } else if(3 == type) {
            LocalDateTime startOfMonth = now.withDayOfMonth(1);
            LocalDateTime startOfStartOfMonth = startOfMonth.with(startOfDayTime);
            LocalDateTime endOfToday = now.with(endOfDayTime);
            startDate = startOfStartOfMonth.format(formatter);
            endDate = endOfToday.format(formatter);
        } else if(4 == type) {
            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);

            LocalDateTime startOfPrevMonthStart = firstDayOfPreviousMonth.with(startOfDayTime);
            LocalDateTime endOfPrevMonthEnd = lastDayOfPreviousMonth.with(endOfDayTime);

            startDate = startOfPrevMonthStart.format(formatter);
            endDate = endOfPrevMonthEnd.format(formatter);
        }

        AnalysisPreviewQueryDTO param = new AnalysisPreviewQueryDTO();
        param.setStartTime(startDate);
        param.setEndTime(endDate);
        param.setType(type);

        param.setUserType(userType);
        List<WatchEndPlayTrendDTO> watchEndPlayTrendDTOS = this.watchEndPlayTrend(param);

        redisCache.setCacheObject(String.format("%s:%d:%d",DATA_OVERVIEW_DEALER_CHARTS,type,userType),watchEndPlayTrendDTOS);

    }


    public void companyWatchCourseTopTenTask0(){
        companyWatchCourseTopTenTask(0,0,1);
        companyWatchCourseTopTenTask(0,1,1);


        companyWatchCourseTopTenTask(0,0,2);
        companyWatchCourseTopTenTask(0,1,2);
    }

    public void companyWatchCourseTopTenTask1(){
        companyWatchCourseTopTenTask(1,0,1);
        companyWatchCourseTopTenTask(1,1,1);
        companyWatchCourseTopTenTask(2,0,1);
        companyWatchCourseTopTenTask(2,1,1);
        companyWatchCourseTopTenTask(3,0,1);
        companyWatchCourseTopTenTask(3,1,1);
        companyWatchCourseTopTenTask(4,0,1);
        companyWatchCourseTopTenTask(4,1,1);

        companyWatchCourseTopTenTask(1,0,2);
        companyWatchCourseTopTenTask(1,1,2);
        companyWatchCourseTopTenTask(2,0,2);
        companyWatchCourseTopTenTask(2,1,2);
        companyWatchCourseTopTenTask(3,0,2);
        companyWatchCourseTopTenTask(3,1,2);
        companyWatchCourseTopTenTask(4,0,2);
        companyWatchCourseTopTenTask(4,1,2);


    }

    @Override
    public void companyWatchCourseTopTenTask(Integer type,Integer statisticalType,Integer userType) {

        AnalysisPreviewQueryDTO dto = new AnalysisPreviewQueryDTO();
        dto.setType(type);
        dto.setStatisticalType(statisticalType);

        String startDate = "";
        String endDate = "";

        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        LocalTime startOfDayTime = LocalTime.MIN;
        LocalTime endOfDayTime = LocalTime.of(23, 59, 59);

        if(0 == type){
            LocalDateTime startOfDay = now.with(startOfDayTime);
            LocalDateTime endOfDay = now.with(endOfDayTime);
            startDate = startOfDay.format(formatter);
            endDate = endOfDay.format(formatter);
        } else if(1 == type){
            LocalDateTime yesterday = now.minusDays(1);
            LocalDateTime startOfYesterday = yesterday.with(startOfDayTime);
            LocalDateTime endOfYesterday = yesterday.with(endOfDayTime);
            startDate = startOfYesterday.format(formatter);
            endDate = endOfYesterday.format(formatter);
        } else if(2 == type) {
            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
            LocalDateTime startOfStartOfWeek = startOfWeek.with(startOfDayTime);
            LocalDateTime endOfToday = now.with(endOfDayTime);
            startDate = startOfStartOfWeek.format(formatter);
            endDate = endOfToday.format(formatter);
        } else if(3 == type) {
            LocalDateTime startOfMonth = now.withDayOfMonth(1);
            LocalDateTime startOfStartOfMonth = startOfMonth.with(startOfDayTime);
            LocalDateTime endOfToday = now.with(endOfDayTime);
            startDate = startOfStartOfMonth.format(formatter);
            endDate = endOfToday.format(formatter);
        } else if(4 == type) {
            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);

            LocalDateTime startOfPrevMonthStart = firstDayOfPreviousMonth.with(startOfDayTime);
            LocalDateTime endOfPrevMonthEnd = lastDayOfPreviousMonth.with(endOfDayTime);

            startDate = startOfPrevMonthStart.format(formatter);
            endDate = endOfPrevMonthEnd.format(formatter);
        }

        dto.setStartTime(startDate);
        dto.setEndTime(endDate);
        dto.setUserType(userType);

        List<DeaMemberTopTenDTO> deaMemberTopTenDTOS = deaMemberTopTen(dto);
        redisCache.setCacheObject(String.format("%s:%d:%d:%d", CHARTS_MEMBER_TOP_TEN_WATCH, type,statisticalType,userType), deaMemberTopTenDTOS);
    }

    @Override
    public void watchCourseTopTenTask(Integer type,Integer statisticalType,Integer userType,String sort) {
        AnalysisPreviewQueryDTO dto = new AnalysisPreviewQueryDTO();
        dto.setType(type);
        dto.setStatisticalType(statisticalType);
        dto.setSort(sort);

        String startDate = "";
        String endDate = "";

        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        LocalTime startOfDayTime = LocalTime.MIN;
        LocalTime endOfDayTime = LocalTime.of(23, 59, 59);

        if(0 == type){
            LocalDateTime startOfDay = now.with(startOfDayTime);
            LocalDateTime endOfDay = now.with(endOfDayTime);
            startDate = startOfDay.format(formatter);
            endDate = endOfDay.format(formatter);
        } else if(1 == type){
            LocalDateTime yesterday = now.minusDays(1);
            LocalDateTime startOfYesterday = yesterday.with(startOfDayTime);
            LocalDateTime endOfYesterday = yesterday.with(endOfDayTime);
            startDate = startOfYesterday.format(formatter);
            endDate = endOfYesterday.format(formatter);
        } else if(2 == type) {
            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
            LocalDateTime startOfStartOfWeek = startOfWeek.with(startOfDayTime);
            LocalDateTime endOfToday = now.with(endOfDayTime);
            startDate = startOfStartOfWeek.format(formatter);
            endDate = endOfToday.format(formatter);
        } else if(3 == type) {
            LocalDateTime startOfMonth = now.withDayOfMonth(1);
            LocalDateTime startOfStartOfMonth = startOfMonth.with(startOfDayTime);
            LocalDateTime endOfToday = now.with(endOfDayTime);
            startDate = startOfStartOfMonth.format(formatter);
            endDate = endOfToday.format(formatter);
        } else if(4 == type) {
            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);

            LocalDateTime startOfPrevMonthStart = firstDayOfPreviousMonth.with(startOfDayTime);
            LocalDateTime endOfPrevMonthEnd = lastDayOfPreviousMonth.with(endOfDayTime);

            startDate = startOfPrevMonthStart.format(formatter);
            endDate = endOfPrevMonthEnd.format(formatter);
        }
        dto.setStartTime(startDate);
        dto.setEndTime(endDate);
        dto.setUserType(userType);
        List<CourseStatsDTO> courseStatsDTOS = watchCourseTopTen(dto);

        redisCache.setCacheObject( String.format("%s:%d:%d:%d:%s", CHARTS_WATCH_TOP_TEN, type,statisticalType,userType,sort), courseStatsDTOS);
    }

    public void watchCourseTopTenTask0(){
        watchCourseTopTenTask(0,0,1,"DESC");
        watchCourseTopTenTask(0,0,1,"ASC");
        watchCourseTopTenTask(0,1,1,"DESC");
        watchCourseTopTenTask(0,1,1,"ASC");
        watchCourseTopTenTask(0,2,1,"DESC");
        watchCourseTopTenTask(0,2,1,"ASC");
        watchCourseTopTenTask(0,3,1,"DESC");
        watchCourseTopTenTask(0,3,1,"ASC");

        watchCourseTopTenTask(0,0,1,"DESC");
        watchCourseTopTenTask(0,0,1,"ASC");
        watchCourseTopTenTask(0,1,1,"DESC");
        watchCourseTopTenTask(0,1,1,"ASC");
        watchCourseTopTenTask(0,2,1,"DESC");
        watchCourseTopTenTask(0,2,1,"ASC");
        watchCourseTopTenTask(0,3,1,"DESC");
        watchCourseTopTenTask(0,3,1,"ASC");
    }

    public void watchCourseTopTenTask1(){
        watchCourseTopTenTask(1,0,1,"DESC");
        watchCourseTopTenTask(1,0,1,"ASC");

        watchCourseTopTenTask(1,0,2,"DESC");
        watchCourseTopTenTask(1,0,2,"ASC");


        watchCourseTopTenTask(1,1,1,"DESC");
        watchCourseTopTenTask(1,1,1,"ASC");

        watchCourseTopTenTask(1,1,2,"DESC");
        watchCourseTopTenTask(1,1,2,"ASC");

        watchCourseTopTenTask(1,2,1,"DESC");
        watchCourseTopTenTask(1,2,1,"ASC");

        watchCourseTopTenTask(1,2,2,"DESC");
        watchCourseTopTenTask(1,2,2,"ASC");


        watchCourseTopTenTask(1,3,1,"DESC");
        watchCourseTopTenTask(1,3,1,"ASC");

        watchCourseTopTenTask(1,3,2,"DESC");
        watchCourseTopTenTask(1,3,2,"ASC");

        watchCourseTopTenTask(2,0,1,"DESC");
        watchCourseTopTenTask(2,0,1,"ASC");

        watchCourseTopTenTask(2,0,2,"DESC");
        watchCourseTopTenTask(2,0,2,"ASC");

        watchCourseTopTenTask(2,1,1,"DESC");
        watchCourseTopTenTask(2,1,1,"ASC");

        watchCourseTopTenTask(2,1,2,"DESC");
        watchCourseTopTenTask(2,1,2,"ASC");

        watchCourseTopTenTask(2,2,1,"DESC");
        watchCourseTopTenTask(2,2,1,"ASC");

        watchCourseTopTenTask(2,2,2,"DESC");
        watchCourseTopTenTask(2,2,2,"ASC");


        watchCourseTopTenTask(2,3,1,"DESC");
        watchCourseTopTenTask(2,3,1,"ASC");

        watchCourseTopTenTask(2,3,2,"DESC");
        watchCourseTopTenTask(2,3,2,"ASC");

        watchCourseTopTenTask(3,0,1,"DESC");
        watchCourseTopTenTask(3,0,1,"ASC");

        watchCourseTopTenTask(3,0,2,"DESC");
        watchCourseTopTenTask(3,0,2,"ASC");

        watchCourseTopTenTask(3,1,1,"DESC");
        watchCourseTopTenTask(3,1,1,"ASC");

        watchCourseTopTenTask(3,1,2,"DESC");
        watchCourseTopTenTask(3,1,2,"ASC");

        watchCourseTopTenTask(3,2,1,"DESC");
        watchCourseTopTenTask(3,2,1,"ASC");

        watchCourseTopTenTask(3,2,2,"DESC");
        watchCourseTopTenTask(3,2,2,"ASC");

        watchCourseTopTenTask(3,3,1,"DESC");
        watchCourseTopTenTask(3,3,1,"ASC");

        watchCourseTopTenTask(3,3,2,"DESC");
        watchCourseTopTenTask(3,3,2,"ASC");

        watchCourseTopTenTask(4,0,1,"DESC");
        watchCourseTopTenTask(4,0,1,"ASC");

        watchCourseTopTenTask(4,0,2,"DESC");
        watchCourseTopTenTask(4,0,2,"ASC");

        watchCourseTopTenTask(4,1,1,"DESC");
        watchCourseTopTenTask(4,1,1,"ASC");
        watchCourseTopTenTask(4,2,1,"DESC");
        watchCourseTopTenTask(4,2,1,"ASC");
        watchCourseTopTenTask(4,3,1,"DESC");
        watchCourseTopTenTask(4,3,1,"ASC");

        watchCourseTopTenTask(4,1,2,"DESC");
        watchCourseTopTenTask(4,1,2,"ASC");
        watchCourseTopTenTask(4,2,2,"DESC");
        watchCourseTopTenTask(4,2,2,"ASC");
        watchCourseTopTenTask(4,3,2,"DESC");
        watchCourseTopTenTask(4,3,2,"ASC");
    }


    public void rewardMoneyTask15Minutes(){
        rewardMoneyTopTenTask(0,0,1);
        rewardMoneyTopTenTask(0,1,1);

        rewardMoneyTradeTask(0,1);

        rewardMoneyTopTenTask(0,0,2);
        rewardMoneyTopTenTask(0,1,2);

        rewardMoneyTradeTask(0,2);
    }


    public void rewardMoneyTaskEveryday(){
        rewardMoneyTopTenTask(1,0,1);
        rewardMoneyTopTenTask(1,1,1);


        rewardMoneyTopTenTask(2,0,1);
        rewardMoneyTopTenTask(2,1,1);

        rewardMoneyTopTenTask(3,0,1);
        rewardMoneyTopTenTask(3,1,1);

        rewardMoneyTopTenTask(4,0,1);
        rewardMoneyTopTenTask(4,1,1);


        rewardMoneyTradeTask(1,1);
        rewardMoneyTradeTask(2,1);
        rewardMoneyTradeTask(3,1);
        rewardMoneyTradeTask(4,1);


        rewardMoneyTopTenTask(1,0,2);
        rewardMoneyTopTenTask(1,1,2);
        rewardMoneyTopTenTask(2,0,2);
        rewardMoneyTopTenTask(2,1,2);
        rewardMoneyTopTenTask(3,0,2);
        rewardMoneyTopTenTask(3,1,2);
        rewardMoneyTopTenTask(4,0,2);
        rewardMoneyTopTenTask(4,1,2);

        rewardMoneyTradeTask(1,2);
        rewardMoneyTradeTask(2,2);
        rewardMoneyTradeTask(3,2);
        rewardMoneyTradeTask(4,2);
    }

    @Override
    public void rewardMoneyTopTenTask(Integer type,Integer dataType,Integer userType) {
        AnalysisPreviewQueryDTO dto = new AnalysisPreviewQueryDTO();
        dto.setType(type);
        dto.setDataType(dataType);

        String startDate = "";
        String endDate = "";

        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        LocalTime startOfDayTime = LocalTime.MIN;
        LocalTime endOfDayTime = LocalTime.of(23, 59, 59);

        if(0 == type){
            LocalDateTime startOfDay = now.with(startOfDayTime);
            LocalDateTime endOfDay = now.with(endOfDayTime);
            startDate = startOfDay.format(formatter);
            endDate = endOfDay.format(formatter);
        } else if(1 == type){
            LocalDateTime yesterday = now.minusDays(1);
            LocalDateTime startOfYesterday = yesterday.with(startOfDayTime);
            LocalDateTime endOfYesterday = yesterday.with(endOfDayTime);
            startDate = startOfYesterday.format(formatter);
            endDate = endOfYesterday.format(formatter);
        } else if(2 == type) {
            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
            LocalDateTime startOfStartOfWeek = startOfWeek.with(startOfDayTime);
            LocalDateTime endOfToday = now.with(endOfDayTime);
            startDate = startOfStartOfWeek.format(formatter);
            endDate = endOfToday.format(formatter);
        } else if(3 == type) {
            LocalDateTime startOfMonth = now.withDayOfMonth(1);
            LocalDateTime startOfStartOfMonth = startOfMonth.with(startOfDayTime);
            LocalDateTime endOfToday = now.with(endOfDayTime);
            startDate = startOfStartOfMonth.format(formatter);
            endDate = endOfToday.format(formatter);
        } else if(4 == type) {
            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);

            LocalDateTime startOfPrevMonthStart = firstDayOfPreviousMonth.with(startOfDayTime);
            LocalDateTime endOfPrevMonthEnd = lastDayOfPreviousMonth.with(endOfDayTime);

            startDate = startOfPrevMonthStart.format(formatter);
            endDate = endOfPrevMonthEnd.format(formatter);
        }

        dto.setStartTime(startDate);
        dto.setEndTime(endDate);
        dto.setUserType(userType);

        List<RewardMoneyTopTenDTO> rewardMoneyTopTenDTOS = rewardMoneyTopTen(dto);

        redisCache.setCacheObject( String.format("%s:%d:%d:%d", CHARTS_REWARD_MONEY_TOP_TEN, type,dataType,userType), rewardMoneyTopTenDTOS);

    }

    @Override
    public void rewardMoneyTradeTask(Integer type,Integer userType) {
        AnalysisPreviewQueryDTO dto = new AnalysisPreviewQueryDTO();
        dto.setType(type);

        String startDate = "";
        String endDate = "";

        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        LocalTime startOfDayTime = LocalTime.MIN;
        LocalTime endOfDayTime = LocalTime.of(23, 59, 59);

        if(0 == type){
            LocalDateTime startOfDay = now.with(startOfDayTime);
            LocalDateTime endOfDay = now.with(endOfDayTime);
            startDate = startOfDay.format(formatter);
            endDate = endOfDay.format(formatter);
        } else if(1 == type){
            LocalDateTime yesterday = now.minusDays(1);
            LocalDateTime startOfYesterday = yesterday.with(startOfDayTime);
            LocalDateTime endOfYesterday = yesterday.with(endOfDayTime);
            startDate = startOfYesterday.format(formatter);
            endDate = endOfYesterday.format(formatter);
        } else if(2 == type) {
            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
            LocalDateTime startOfStartOfWeek = startOfWeek.with(startOfDayTime);
            LocalDateTime endOfToday = now.with(endOfDayTime);
            startDate = startOfStartOfWeek.format(formatter);
            endDate = endOfToday.format(formatter);
        } else if(3 == type) {
            LocalDateTime startOfMonth = now.withDayOfMonth(1);
            LocalDateTime startOfStartOfMonth = startOfMonth.with(startOfDayTime);
            LocalDateTime endOfToday = now.with(endOfDayTime);
            startDate = startOfStartOfMonth.format(formatter);
            endDate = endOfToday.format(formatter);
        } else if(4 == type) {
            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);

            LocalDateTime startOfPrevMonthStart = firstDayOfPreviousMonth.with(startOfDayTime);
            LocalDateTime endOfPrevMonthEnd = lastDayOfPreviousMonth.with(endOfDayTime);

            startDate = startOfPrevMonthStart.format(formatter);
            endDate = endOfPrevMonthEnd.format(formatter);
        }

        dto.setStartTime(startDate);
        dto.setEndTime(endDate);
        dto.setUserType(userType);
        List<RewardMoneyTrendDTO> rewardMoneyTrendDTOS = rewardMoneyTrendDTO(dto);
        redisCache.setCacheObject( String.format("%s:%d:%d", CHARTS_REWARD_MONEY_TREND, type,userType), rewardMoneyTrendDTOS);

    }



    @Override
    public DealerAggregatedDTO dealerAggregated() {
        Long dayUserCount=userService.selectFsUserCount(1,null, null);
        Long storeOrderCount=storeOrderService.selectFsStoreOrderTotalCount(0,null);
        Long dayStoreOrderCount=storeOrderService.selectFsStoreOrderTotalCount(1,null);
        Long paymentCount=paymentService.selectFsStorePaymentCount(0,null);
        Long dayPaymentCount=paymentService.selectFsStorePaymentCount(1,null);
        Long productCount=productService.selectFsStoreProductCount(0);
        Long dayProductCount=productService.selectFsStoreProductCount(1);
        QwIpadServer padInfo=qwIpadServerService.getPadInfo();
        DealerAggregatedDTO dealerAggregatedDTO = consumptionBalanceMapper.dealerAggregated();
        dealerAggregatedDTO.setTodayIncreaseUserNum(dayUserCount);
        dealerAggregatedDTO.setOrderTotalNum(storeOrderCount);
        dealerAggregatedDTO.setTodayOrderNum(dayStoreOrderCount);
        dealerAggregatedDTO.setRecvTodayNum(paymentCount);
        dealerAggregatedDTO.setRecvTodayNum(dayPaymentCount);
        dealerAggregatedDTO.setGoodsTotalNum(productCount);
        dealerAggregatedDTO.setTodayGoodsNum(dayProductCount);
        if (padInfo != null){
            dealerAggregatedDTO.setPadTotalNum(padInfo.getTotalCount());
            dealerAggregatedDTO.setPadUsedNum(padInfo.getCount());
        }
        return dealerAggregatedDTO;
    }

    @Override
    public ConsumptionBalanceDataDTO rechargeConsumption() {
        // 获取流量统计数据
        TrafficLogDTO trafficLog = this.getTrafficLog();

        // 获取流量价格配置
        SysConfig config = configService.selectConfigByConfigKey("statis.config");
        Asserts.notNull(config, "流量价格配置不能为空!");
        JSONObject jsonObject = JSONObject.parseObject(config.getConfigValue());
        float trafficPrice = jsonObject.getFloatValue("trafficPrice");

        // 创建消费余额数据对象
        ConsumptionBalanceDataDTO consumptionBalanceData = new ConsumptionBalanceDataDTO();

        // 计算消费金额（将流量从字节转换为GB，然后乘以每GB价格）
        BigDecimal todayConsumption = calculateTrafficCost(trafficLog.getToday(), trafficPrice);
        BigDecimal yesterdayConsumption = calculateTrafficCost(trafficLog.getYesterday(), trafficPrice);

        // 设置消费数据
        consumptionBalanceData.setTodayComsumption(todayConsumption);
        consumptionBalanceData.setYesterdayComsumption(yesterdayConsumption);

        // 从数据库获取当前余额
        BigDecimal currentBalance = consumptionBalanceMapper.getCurrentBalance();
        consumptionBalanceData.setBalance(currentBalance);

        return consumptionBalanceData;
    }
    /**
     * 计算流量消费金额
     * @param trafficBytes 流量字节数
     * @param pricePerGB 每GB价格
     * @return 消费金额
     */
    private BigDecimal calculateTrafficCost(Long trafficBytes, float pricePerGB) {
        if (trafficBytes == null || trafficBytes <= 0) {
            return BigDecimal.ZERO;
        }

        // 将字节转换为GB (1GB = 1024^3 bytes)
        BigDecimal trafficGB = new BigDecimal(trafficBytes)
                .divide(new BigDecimal(1024 * 1024 * 1024), 6, BigDecimal.ROUND_HALF_UP);

        // 计算消费金额
        return trafficGB.multiply(new BigDecimal(pricePerGB)).setScale(2, BigDecimal.ROUND_HALF_UP);
    }
    @Override
    public AnalysisPreviewDTO analysisPreview(AnalysisPreviewQueryDTO param) {
        AnalysisPreviewDTO dto = new AnalysisPreviewDTO();

        Long watchUserCount = consumptionBalanceMapper.queryWatchUserCount(param);
        Long completedUserCount = consumptionBalanceMapper.queryCompletedUserCount(param);

        if(watchUserCount == null){
            watchUserCount = 0L;
        }
        if(completedUserCount == null){
            completedUserCount = 0L;
        }

        // 观看人数
        dto.setWatchUserCount(watchUserCount);
        // 完播人数
        dto.setCompletedUserCount(completedUserCount);

        // 完播率
        if(!ObjectUtils.equals(watchUserCount,0L)){
            BigDecimal multiply = (BigDecimal.valueOf(completedUserCount)
                    .divide(BigDecimal.valueOf(watchUserCount),4,BigDecimal.ROUND_HALF_UP))
                    .multiply(BigDecimal.valueOf(100));

            dto.setCompletedRate(multiply.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString());
        } else {
            dto.setCompletedRate("0");
        }

        Long watchCount = consumptionBalanceMapper.queryWatchCount(param);
        Long completedCount = consumptionBalanceMapper.queryCompletedCount(param);

        if(watchCount == null){
            watchCount = 0L;
        }
        if(completedCount == null){
            completedCount = 0L;
        }

        // 观看次数
        dto.setWatchCount(watchCount);
        // 完播次数
        dto.setCompletedCount(completedCount);
        // 视频完播率
        if(!ObjectUtils.equals(watchCount, 0L)){
            BigDecimal multiply = BigDecimal.valueOf(completedCount)
                    .divide(BigDecimal.valueOf(watchCount),4,BigDecimal.ROUND_HALF_UP)
                    .multiply(BigDecimal.valueOf(100));

            dto.setWatchRate(multiply.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString());
        } else {
            dto.setWatchRate("0");
        }

        Long answerMemberCount = consumptionBalanceMapper.queryAnswerMemberCount(param);
        Long correctUserCount = consumptionBalanceMapper.queryCorrectUserCount(param);

        if(answerMemberCount == null){
            answerMemberCount = 0L;
        }
        if(correctUserCount == null){
            correctUserCount = 0L;
        }
        // 答题人数
        dto.setAnswerMemberCount(answerMemberCount);
        // 正确人数
        dto.setCorrectUserCount(correctUserCount);
        // 正确比例
        if(!ObjectUtils.equals(answerMemberCount, 0L)){
            BigDecimal multiply = BigDecimal.valueOf(correctUserCount)
                    .divide(BigDecimal.valueOf(answerMemberCount),4,BigDecimal.ROUND_HALF_UP)
                    .multiply(BigDecimal.valueOf(100));

            dto.setCorrectRate(multiply.setScale(2, RoundingMode.HALF_UP).toPlainString());
        } else {
            dto.setCorrectRate("0");
        }
        Long rewardCount = consumptionBalanceMapper.queryRewardCount(param);
        if(rewardCount == null) {
            rewardCount = 0L;
        }
        BigDecimal rewardMoney = consumptionBalanceMapper.queryRewardMoney(param);
        if(rewardMoney == null) {
            rewardMoney = BigDecimal.ZERO;
        }
        // 答题红包个数
        dto.setRewardCount(rewardCount);
        // 答题红包金额
        dto.setRewardMoney(rewardMoney);

        return dto;
    }

    @Override
    public Long smsBalance() {
        Long smsBalance = consumptionBalanceMapper.smsBalance();
        if(smsBalance != null) {
            smsBalance = 0L;
        }
        return smsBalance;
    }

    @Override
    public AuthorizationInfoDTO authorizationInfo() {
        return consumptionBalanceMapper.authorizationInfo();
    }

    @Override
    public List<WatchEndPlayTrendDTO> watchEndPlayTrend(AnalysisPreviewQueryDTO param) {
        List<WatchEndPlayTrendDTO> watchEndPlayTrendDTOS = consumptionBalanceMapper.watchEndPlayTrend(param);
        // 今日，昨日 格式为24小时
        if(ObjectUtils.equals(param.getType(),0) || ObjectUtils.equals(param.getType(),1)){
            watchEndPlayTrendDTOS = TrendDataFiller.fillHourData(watchEndPlayTrendDTOS);
            // 否则都是按天为维度的时间范围
        } else {
            watchEndPlayTrendDTOS = TrendDataFiller.fillDateSegmentData(watchEndPlayTrendDTOS, param.getStartTime(), param.getEndTime());
        }

        return watchEndPlayTrendDTOS;
    }

    @Override
    public List<DeaMemberTopTenDTO> deaMemberTopTen(AnalysisPreviewQueryDTO param) {
        List<DeaMemberTopTenDTO> deaMemberTopTenDTOS = consumptionBalanceMapper.deaMemberTopTen(param);
        for (DeaMemberTopTenDTO dto : deaMemberTopTenDTOS) {
            Long companyId = dto.getCompanyId();
            String companyName = companyCacheService.selectCompanyNameById(companyId);
            if(StringUtils.isNotBlank(companyName)){
                dto.setCompanyName(companyName);
            }
        }
        return deaMemberTopTenDTOS;
    }

    @Override
    public List<CourseStatsDTO> watchCourseTopTen(AnalysisPreviewQueryDTO param) {
//        List<CourseStatsDTO> courseStatsDTOS = consumptionBalanceMapper.watchCourseTopTen(param);
//        for (CourseStatsDTO courseStatsDTO : courseStatsDTOS) {
//            String courseName = fsUserCourseCacheService.selectCourseNameByCourseId(courseStatsDTO.getCourseId());
//            if(StringUtils.isNotBlank(courseName)){
//                courseStatsDTO.setCourseName(courseName);
//            }
//        }
//        return courseStatsDTOS;
        // 1. 根据统计类型获取基础数据
        List<CourseStatsDTO> result = getBaseCourseStats(param);

        // 2. 如果查询的是观看或完成数据，需要补充答题数据
        if (param.getStatisticalType() == 0 || param.getStatisticalType() == 1) {
            supplementAnswerData(result, param);
        }

        // 3. 设置课程名称
        setCourseNames(result);

        return result;
    }

    /**
     * 获取基础课程统计数据
     */
    private List<CourseStatsDTO> getBaseCourseStats(AnalysisPreviewQueryDTO param) {
        Integer statisticalType = param.getStatisticalType();
        switch (statisticalType) {
            case 0: // 观看人数
                return consumptionBalanceMapper.watchCourseTopTenByWatch(param);
            case 1: // 完成人数
                return consumptionBalanceMapper.watchCourseTopTenByComplete(param);
            case 2: // 答题人数
                return consumptionBalanceMapper.watchCourseTopTenByAnswer(param);
            case 3: // 正确人数
                return consumptionBalanceMapper.watchCourseTopTenByCorrect(param);
            default:
                return consumptionBalanceMapper.watchCourseTopTenByWatch(param);
        }
    }

    /**
     * 补充答题数据（针对观看和完成统计）
     */
    private void supplementAnswerData(List<CourseStatsDTO> result, AnalysisPreviewQueryDTO param) {
        if (result == null || result.isEmpty()) {
            return;
        }

        // 提取课程ID列表
        List<Long> courseIds = result.stream()
                .map(CourseStatsDTO::getCourseId)
                .collect(Collectors.toList());

        // 批量查询答题数据
        List<CourseStatsDTO> answerStats = consumptionBalanceMapper.getAnswerStatsByCourseIds(courseIds, param);

        // 构建课程ID到答题数据的映射
        Map<Long, CourseStatsDTO> answerMap = answerStats.stream()
                .collect(Collectors.toMap(CourseStatsDTO::getCourseId, Function.identity()));

        // 合并答题数据到结果中
        for (CourseStatsDTO dto : result) {
            CourseStatsDTO answerStat = answerMap.get(dto.getCourseId());
            if (answerStat != null) {
                dto.setAnswerUserCount(answerStat.getAnswerUserCount());
                dto.setCorrectUserCount(answerStat.getCorrectUserCount());
            }
            // 如果没有答题数据，保持原来的0值
        }
    }

    /**
     * 设置课程名称
     */
    private void setCourseNames(List<CourseStatsDTO> result) {
        for (CourseStatsDTO courseStatsDTO : result) {
            String courseName = fsUserCourseCacheService.selectCourseNameByCourseId(courseStatsDTO.getCourseId());
            if (StringUtils.isNotBlank(courseName)) {
                courseStatsDTO.setCourseName(courseName);
            }
        }
    }

    @Override
    public List<RewardMoneyTopTenDTO> rewardMoneyTopTen(AnalysisPreviewQueryDTO param) {
        List<RewardMoneyTopTenDTO> rewardMoneyTopTenDTOS = consumptionBalanceMapper.rewardMoneyTopTen(param);
        for (RewardMoneyTopTenDTO dto : rewardMoneyTopTenDTOS) {
            if(dto.getCompanyId() != null) {
                String companyName = companyCacheService.selectCompanyNameById(dto.getCompanyId());
                dto.setCompanyName(companyName);
            }
            if(dto.getCourseId() != null){
                String courseName = fsUserCourseCacheService.selectCourseNameByCourseId(dto.getCourseId());
                dto.setCourseName(courseName);
            }

        }
        return rewardMoneyTopTenDTOS;
    }

    @Override
    public List<RewardMoneyTrendDTO> rewardMoneyTrendDTO(AnalysisPreviewQueryDTO param) {
        List<RewardMoneyTrendDTO> rewardMoneyTrendDTOS = consumptionBalanceMapper.rewardMoneyTrendDTO(param);

        // 今日，昨日 格式为24小时
        if(ObjectUtils.equals(param.getType(),0) || ObjectUtils.equals(param.getType(),1)){
            rewardMoneyTrendDTOS = TrendDataFiller.fillRewardHourData(rewardMoneyTrendDTOS);
            // 否则都是按天为维度的时间范围
        } else {
            rewardMoneyTrendDTOS = TrendDataFiller.fillRewardDateSegmentData(rewardMoneyTrendDTOS, param.getStartTime(), param.getEndTime());
        }


        return rewardMoneyTrendDTOS;
    }

    @Override
    public TrafficLogDTO getTrafficLog() {
        TrafficLogDTO trafficLogDTO = new TrafficLogDTO();
        Long todayTrafficLog = fsCourseTrafficLogMapper.getTodayTrafficLog();
        Long yesterdayTrafficLog = fsCourseTrafficLogMapper.getYesterdayTrafficLog();
        Long monthTrafficLog = fsCourseTrafficLogMapper.getMonthTrafficLog();
        trafficLogDTO.setToday(todayTrafficLog);
        trafficLogDTO.setThisMonth(monthTrafficLog);
        trafficLogDTO.setYesterday(yesterdayTrafficLog);
        return trafficLogDTO;
    }

    @Override
    public void thisMonthOrderCount() {
        Long[] users=new Long[0];
        TimeUtils.TimeEntity timeEntity=TimeUtils.parseTime("5",null,null);
        timeEntity.setUserIds(users);
        Integer cycleNum = timeEntity.getCycleNum();
        Integer beginTime = timeEntity.getBeginTime();
        List<Integer> timeList = new ArrayList<>();
        for (int i = 1; i <= cycleNum; i++) {
            timeList.add(beginTime);
            beginTime = TimeUtils.formatTime(beginTime);
        }
        List<JSONObject> jsonObjectList = storeOrderService.selectFsStoreOrderCounts(timeEntity.toMap());
        List<String> dates = jsonObjectList.stream().map(jsonObject -> jsonObject.getString("type")).collect(Collectors.toList());
        List<Integer> orderCount = jsonObjectList.stream().map(jsonObject -> jsonObject.getInteger("orderCount")).collect(Collectors.toList());
        List<Integer> payPrice = jsonObjectList.stream().map(jsonObject -> jsonObject.getInteger("payPrice")).collect(Collectors.toList());
        R result = R.ok().put("dates", dates).put("orderCount", orderCount).put("payPrice", payPrice);
        redisCache.setCacheObject(THIS_MONTH_ORDER_COUNT,result);
    }

    @Override
    public void thisMonthRecvCount() {
        Long[] users=new Long[0];
        TimeUtils.TimeEntity timeEntity=TimeUtils.parseTime("5",null,null);
        timeEntity.setUserIds(users);
        Integer cycleNum = timeEntity.getCycleNum();
        Integer beginTime = timeEntity.getBeginTime();
        List<Integer> timeList = new ArrayList<>();
        for (int i = 1; i <= cycleNum; i++) {
            timeList.add(beginTime);
            beginTime = TimeUtils.formatTime(beginTime);
        }
        List<JSONObject> jsonObjectList = paymentService.selectFsStorePaymentCounts(timeEntity.toMap());
        List<String> dates = jsonObjectList.stream().map(jsonObject -> jsonObject.getString("type")).collect(Collectors.toList());
        List<Integer> orderCount = jsonObjectList.stream().map(jsonObject -> jsonObject.getInteger("orderCount")).collect(Collectors.toList());
        List<Float> payMoney = jsonObjectList.stream().map(jsonObject -> jsonObject.getFloatValue("payMoney")).collect(Collectors.toList());
        R result = R.ok().put("dates", dates).put("orderCount", orderCount).put("payMoney", payMoney);
        redisCache.setCacheObject(THIS_MONTH_RECV_COUNT,result);
    }

    @Override
    public WatchCourseStatisticsDTO queryWatchCourse(com.fs.statistics.param.WatchCourseStatisticsParam param) {
        List<WatchLogDTO> data = null;
        // 七天
        if(ObjectUtils.equals(param.getType(),0)) {
            data = fsCourseWatchLogMapper.selectFsCourseWatchLog7Day(param.getQwExternalContactId());
        } else if(ObjectUtils.equals(param.getType(),1)){
            data = fsCourseWatchLogMapper.selectFsCourseWatchLog30DayByExtId(param.getQwExternalContactId());
        }

        WatchCourseStatisticsDTO watchCourseStatisticsDTO = new WatchCourseStatisticsDTO();
        watchCourseStatisticsDTO.setData(data);

        return watchCourseStatisticsDTO;
    }

    /**
     * @Description: 统计按TimeType 0-今天，1-昨天，2-本周，3-本月，4-上月；各公司的观看人数和完播人数, 存到redis中，定时任务每 ? 分钟执行一次
     * @Param:
     * @Return:
     * @Author xgb
     * @Date 2025/10/27 13:09
     */
    @Override
    public void watchCourseStatisticsGroupByCompany() {
        for(int i = 0; i < 5; i++){
            Map<String,Object> params=new HashMap<>();
            DateTimeEntity timeEntity =DateUtils.getBetweenTime(i);
            params.put("startTime",timeEntity.getStartTime());
            params.put("endTime",timeEntity.getEndTime());

            List<WatchCourseStatisticsResultDTO> watchCourseStatisticsDTOS=fsCourseWatchLogMapper.watchCourseStatisticsGroupByCompany(params);
            // 存到redis中 按TimeType 0-今天，1-昨天，2-本周，3-本月，4-上月；
            redisCache.setCacheObject(FsConstants.WATCH_COURSE_STATISTICS_GROUP_COMPANY+i, JSON.toJSONString(watchCourseStatisticsDTOS));
        }
    }

    @Override
    public List<WatchCourseStatisticsResultDTO> getWatchCourseStatisticsData(AnalysisPreviewQueryDTO param) {

        if (param.getType().equals(5)){
            HashMap<String, Object> map = MapUtil.newHashMap();
            map.put("startTime", param.getStartTime());
            map.put("endTime", param.getEndTime());
            return fsCourseWatchLogMapper.watchCourseStatisticsGroupByCompany(map);
        }
        String redisData = redisCache.getCacheObject(FsConstants.WATCH_COURSE_STATISTICS_GROUP_COMPANY + param.getType());
        List<WatchCourseStatisticsResultDTO> watchCourseStatisticsDTOS = new ArrayList<>();
        if (StringUtils.isNotBlank(redisData)) {
            watchCourseStatisticsDTOS = JSONObject.parseArray(redisData, WatchCourseStatisticsResultDTO.class);
        }
        String sendType;
        if (param.getUserType() == 1) {
            sendType = "1";
        } else if (param.getUserType() == 2) {
            sendType = "2";
        } else {
            return new ArrayList<>();
        }

        watchCourseStatisticsDTOS = watchCourseStatisticsDTOS.stream()
                .filter(dto -> StringUtils.equals(sendType, dto.getSendType()))
                .filter(dto -> param.getCompanyId() == null ||
                        StringUtils.equals(dto.getCompanyId(), String.valueOf(param.getCompanyId())))
                .collect(Collectors.toList());


        return watchCourseStatisticsDTOS;
    }
}
