package com.fs.statis.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fs.common.core.domain.R;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.utils.TimeUtils;
import com.fs.company.cache.ICompanyCacheService;
import com.fs.company.service.ICompanyService;
import com.fs.course.mapper.FsCourseTrafficLogMapper;
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.his.vo.OptionsVO;
import com.fs.qw.domain.QwUser;
import com.fs.qw.mapper.QwUserMapper;
import com.fs.statis.StatisticsRedisConstant;
import com.fs.statis.dto.*;
import com.fs.statis.mapper.ConsumptionBalanceMapper;
import com.fs.statis.service.IStatisticsCompanyService;
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.util.ObjectUtils;
import com.hc.openapi.tool.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
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.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

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

@Slf4j
@Service("statisticsCompanyService")
public class StatisticsCompanyServiceImpl implements IStatisticsCompanyService {
    @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 ICompanyService companyService;

    @Autowired
    private QwUserMapper qwUserMapper;
    @Override
    public void dataOverviewTask() {
        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList(null);
        for (OptionsVO optionsVO : optionsVOS) {
            Long companyId = optionsVO.getDictValue();
            if(companyId == null){
                continue;
            }
            dataOverviewTaskCompany(companyId);
        }
    }

    private void dataOverviewTaskCompany(Long companyId){
        DealerAggregatedDTO dealerAggregatedDTO = this.dealerAggregated(companyId);
        ConsumptionBalanceDataDTO consumptionBalanceDataDTO = this.rechargeConsumption(companyId);
        AuthorizationInfoDTO authorizationInfoDTO = authorizationInfo();
        Long smsBalance = this.smsBalance(companyId);
        TrafficLogDTO trafficLog = this.getTrafficLog(companyId);

        redisCache.setCacheObject(String.format(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AGGREGATED+":%d",companyId), dealerAggregatedDTO);
        redisCache.setCacheObject(String.format(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_BALANCE+":%d",companyId), consumptionBalanceDataDTO);
        redisCache.setCacheObject(String.format(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AUTHORIZATION_INFO+":%d",companyId), authorizationInfoDTO);
        redisCache.setCacheObject(String.format(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_SMS_BALANCE+":%d",companyId), smsBalance);
        redisCache.setCacheObject(String.format(StatisticsRedisConstant.DATA_OVERVIEW_TRAFFIC_LOG+":%d",companyId),trafficLog);
    }
    public void analysisPreviewTask0(){
        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList(null);
        for (OptionsVO optionsVO : optionsVOS) {
            Long companyId = optionsVO.getDictValue();
            if (companyId == null) {
                continue;
            }
            analysisPreviewTask(0,1,companyId);
            analysisPreviewTask(0,2,companyId);
        }

    }

    public void analysisPreviewTask1(){
        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList(null);
        for (OptionsVO optionsVO : optionsVOS) {
            Long companyId = optionsVO.getDictValue();
            if (companyId == null) {
                continue;
            }

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

            analysisPreviewTask(0,2,companyId);
            analysisPreviewTask(1,2,companyId);
            analysisPreviewTask(2,2,companyId);
            analysisPreviewTask(3,2,companyId);
            analysisPreviewTask(4,2,companyId);
        }
    }
    @Override
    public void analysisPreviewTask(Integer type, Integer userType,Long companyId) {
        // 根据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);
        param.setCompanyId(companyId);

        AnalysisPreviewDTO analysisPreviewDTO = this.analysisPreview(param);

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


    public void watchEndPlayTrendTask0(){
        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList(null);
        for (OptionsVO optionsVO : optionsVOS) {
            Long companyId = optionsVO.getDictValue();
            if(companyId == null){
                continue;
            }
            this.watchEndPlayTrendTask(0,1,companyId);
            this.watchEndPlayTrendTask(0,2,companyId);
        }

    }

    public void watchEndPlayTrendTask1(){
        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList(null);
        for (OptionsVO optionsVO : optionsVOS) {
            Long companyId = optionsVO.getDictValue();
            if(companyId == null){
                continue;
            }
            this.watchEndPlayTrendTask(1,1,companyId);
            this.watchEndPlayTrendTask(2,1,companyId);
            this.watchEndPlayTrendTask(3,1,companyId);
            this.watchEndPlayTrendTask(4,1,companyId);

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

    }
    @Override
    public void watchEndPlayTrendTask(Integer type, Integer userType,Long companyId) {
        // 根据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.setCompanyId(companyId);

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

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

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

        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);
        dto.setCompanyId(companyId);

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

    public void companyWatchCourseTopTenTask0(){
        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList(null);
        for (OptionsVO optionsVO : optionsVOS) {
            Long companyId = optionsVO.getDictValue();
            if (companyId == null) {
                continue;
            }
            companyWatchCourseTopTenTask(0,0,1,companyId);
            companyWatchCourseTopTenTask(0,1,1,companyId);


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

    }

    public void companyWatchCourseTopTenTask1(){
        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList(null);
        for (OptionsVO optionsVO : optionsVOS) {
            Long companyId = optionsVO.getDictValue();
            if (companyId == null) {
                continue;
            }
            companyWatchCourseTopTenTask(1,0,1,companyId);
            companyWatchCourseTopTenTask(1,1,1,companyId);
            companyWatchCourseTopTenTask(2,0,1,companyId);
            companyWatchCourseTopTenTask(2,1,1,companyId);
            companyWatchCourseTopTenTask(3,0,1,companyId);
            companyWatchCourseTopTenTask(3,1,1,companyId);
            companyWatchCourseTopTenTask(4,0,1,companyId);
            companyWatchCourseTopTenTask(4,1,1,companyId);

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



    }

    @Override
    public void watchCourseTopTenTask(Integer type, Integer statisticalType, Integer userType, String sort,Long companyId) {
        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);
        dto.setCompanyId(companyId);
        List<CourseStatsDTO> courseStatsDTOS = watchCourseTopTen(dto);

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

    }


    public void watchCourseTopTenTask0(){
        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList(null);
        for (OptionsVO optionsVO : optionsVOS) {
            Long companyId = optionsVO.getDictValue();
            if (companyId == null) {
                continue;
            }

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

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

        }

    }

    public void watchCourseTopTenTask1(){
        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList(null);
        for (OptionsVO optionsVO : optionsVOS) {
            Long companyId = optionsVO.getDictValue();
            if (companyId == null) {
                continue;
            }

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

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


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

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

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

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


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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

    }


    @Override
    public void rewardMoneyTopTenTask(Integer type, Integer dataType, Integer userType,Long companyId) {
        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);
        dto.setCompanyId(companyId);

        List<RewardMoneyTopTenDTO> rewardMoneyTopTenDTOS = rewardMoneyTopTen(dto);

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

    }

    @Override
    public void rewardMoneyTradeTask(Integer type, Integer userType,Long companyId) {
        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);
        dto.setCompanyId(companyId);
        List<RewardMoneyTrendDTO> rewardMoneyTrendDTOS = rewardMoneyTrendDTO(dto);
        redisCache.setCacheObject( String.format("%s:%d:%d:%d", CHARTS_REWARD_MONEY_TREND, type,userType,companyId), rewardMoneyTrendDTOS);

    }


    public void rewardMoneyTask15Minutes(){
        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList(null);
        for (OptionsVO optionsVO : optionsVOS) {
            Long companyId = optionsVO.getDictValue();
            if (companyId == null) {
                continue;
            }
            rewardMoneyTopTenTask(0,0,1,companyId);
            rewardMoneyTopTenTask(0,1,1,companyId);

            rewardMoneyTradeTask(0,1,companyId);

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

            rewardMoneyTradeTask(0,2,companyId);
        }

    }


    public void rewardMoneyTaskEveryday(){
        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList(null);
        for (OptionsVO optionsVO : optionsVOS) {
            Long companyId = optionsVO.getDictValue();
            if (companyId == null) {
                continue;
            }

            rewardMoneyTopTenTask(1,0,1,companyId);
            rewardMoneyTopTenTask(1,1,1,companyId);


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

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

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


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


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

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

    }

    @Override
    public DealerAggregatedDTO dealerAggregated(Long companyId) {
        Long dayUserCount=userService.selectFsUserCount(1,companyId, null);
        Long storeOrderCount=storeOrderService.selectFsStoreOrderTotalCount(0,companyId);
        Long dayStoreOrderCount=storeOrderService.selectFsStoreOrderTotalCount(1,companyId);
        Long paymentCount=paymentService.selectFsStorePaymentCount(0,companyId);
        Long dayPaymentCount=paymentService.selectFsStorePaymentCount(1,companyId);
        Long productCount=productService.selectFsStoreProductCount(0,companyId);
        Long dayProductCount=productService.selectFsStoreProductCount(1,companyId);
        //company表中的pad信息
        Long padTotalNum=companyService.selectCompanyById(companyId).getMaxPadNum().longValue();
        //qw_user获取
        Long padUsedNum= qwUserMapper.selectCount(new LambdaQueryWrapper<QwUser>().eq(QwUser::getCompanyId, companyId).isNotNull(QwUser::getServerId)).longValue();
        DealerAggregatedDTO dealerAggregatedDTO = consumptionBalanceMapper.dealerAggregatedCompanyId(companyId);
        dealerAggregatedDTO.setTodayIncreaseUserNum(dayUserCount);
        dealerAggregatedDTO.setOrderTotalNum(storeOrderCount);
        dealerAggregatedDTO.setTodayOrderNum(dayStoreOrderCount);
        dealerAggregatedDTO.setRecvTodayNum(paymentCount);
        dealerAggregatedDTO.setRecvTodayNum(dayPaymentCount);
        dealerAggregatedDTO.setGoodsTotalNum(productCount);
        dealerAggregatedDTO.setTodayGoodsNum(dayProductCount);
        dealerAggregatedDTO.setPadTotalNum(padTotalNum);
        dealerAggregatedDTO.setPadUsedNum(padUsedNum);
        return dealerAggregatedDTO;
    }

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

        // 获取流量价格配置
        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.getCurrentBalanceCompanyId(companyId);
        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 companyId) {
        Long smsBalance = consumptionBalanceMapper.smsBalanceCompany(companyId);
        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);
        for (WatchEndPlayTrendDTO watchEndPlayTrendDTO : watchEndPlayTrendDTOS) {
            watchEndPlayTrendDTO.setX(watchEndPlayTrendDTO.getStartDate());
        }
        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;
        //2025.11.07 优化
        // 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(Long companyId) {
        TrafficLogDTO trafficLogDTO = new TrafficLogDTO();
        Long todayTrafficLog = fsCourseTrafficLogMapper.getTodayTrafficLogCompanyId(companyId);
        Long yesterdayTrafficLog = fsCourseTrafficLogMapper.getYesterdayTrafficLogCompanyId(companyId);
        Long monthTrafficLog = fsCourseTrafficLogMapper.getMonthTrafficLogCompanyId(companyId);
        trafficLogDTO.setToday(todayTrafficLog);
        trafficLogDTO.setThisMonth(monthTrafficLog);
        trafficLogDTO.setYesterday(yesterdayTrafficLog);
        return trafficLogDTO;
    }

    public void companyThisMonthOrderCount(){
        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList(null);
        for (OptionsVO optionsVO : optionsVOS) {
            Long companyId = optionsVO.getDictValue();
            if (companyId == null) {
                continue;
            }
            this.thisMonthOrderCount(companyId);
            this.thisMonthRecvCount(companyId);
        }
    }
    @Override
    public void thisMonthOrderCount(Long companyId) {
        Long[] users=new Long[0];
        TimeUtils.TimeEntity timeEntity=TimeUtils.parseTime("5",null,null);
        timeEntity.setUserIds(users);
        timeEntity.setCompanyId(companyId);
        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(String.format(THIS_MONTH_ORDER_COUNT+":%d",companyId),result);
    }

    @Override
    public void thisMonthRecvCount(Long companyId) {
        Long[] users=new Long[0];
        TimeUtils.TimeEntity timeEntity=TimeUtils.parseTime("5",null,null);
        timeEntity.setUserIds(users);
        timeEntity.setCompanyId(companyId);
        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(String.format(THIS_MONTH_RECV_COUNT+":%d",companyId),result);
    }
}
