package com.kxs.stat.biz.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kxs.common.core.constant.CommonConstants;
import com.kxs.common.core.constant.SecurityConstants;
import com.kxs.common.core.exception.GlobalCustomerException;
import com.kxs.common.core.util.AssertUtil;
import com.kxs.common.core.util.R;
import com.kxs.common.security.util.SecurityUtils;
import com.kxs.stat.api.dto.statUser.StatUserGetMyTradeDTO;
import com.kxs.stat.api.dto.statUser.StatUserGetTradeDetailDTO;
import com.kxs.stat.api.dto.statUser.StatUserGetUserStatByDayOrMonthDTO;
import com.kxs.stat.api.dto.statUser.StatUserGetUserTradeListDTO;
import com.kxs.stat.api.model.KxsLkbTrade;
import com.kxs.stat.api.model.KxsUserActTrade;
import com.kxs.stat.api.model.KxsUserLogoutTrade;
import com.kxs.stat.api.model.KxsUserTrade;
import com.kxs.stat.api.vo.ShdTradeAmtVO;
import com.kxs.stat.api.vo.TotalTradeAmtVO;
import com.kxs.stat.api.vo.statUser.*;
import com.kxs.stat.biz.constant.enums.TotalTypeEnum;
import com.kxs.stat.biz.mapper.*;
import com.kxs.stat.biz.service.KxsUserTradeService;
import com.kxs.user.api.dto.kxsapp.IntegralStatDTO;
import com.kxs.user.api.feign.RemoteKxsUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cursor.Cursor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 个人交易统计总表(KxsUserTrade)表服务实现类
 *
 * @author 系统
 * @since 2024-05-07 17:25:06
 */
@Service("kxsUserTradeService")
@RequiredArgsConstructor
@Slf4j
public class KxsUserTradeServiceImpl extends ServiceImpl<KxsUserTradeMapper, KxsUserTrade> implements KxsUserTradeService {
    private final RemoteKxsUserService remoteKxsUserService;

    private final PlatformTransactionManager platformTransactionManager;

    private final KxsUserActTradeMapper kxsUserActTradeMapper;

    private final KxsLkbTradeMapper kxsLkbTradeMapper;

    private final KxsUserLogoutTradeMapper kxsUserLogoutTradeMapper;

    private final KxsUserNewTradeMapper kxsUserNewTradeMapper;

    private final KxsZlbTradeMapper kxsZlbTradeMapper;
    private final static String PREFIX_TABLE_NAME = "kxs_user_trade_";

    private final static String PREFIX_TABLE_NAME_AFTER = "kxs_user_trade_after_";
    private final static String PREFIX_TABLE_NAME_BEFORE = "kxs_user_trade_before_";


    private final static String PREFIX_TABLE_NAME_TEMP = "kxs_user_trade_temp_";
    private final KxsUserGdTradeMapper kxsUserGdTradeMapper;
    private final KxsLkbActTradeMapper kxsLkbActTradeMapper;

    @Override
    @Async
    public void getUserTradeList(String para) {
        //拼接表名
        String thisMoth;
        //如果定时任务传了参数就使用定时任务的参数
        if (StrUtil.isNotBlank(para)) {
            thisMoth = para;
        } else {
            thisMoth = LocalDateTimeUtil.format(LocalDate.now(), DatePattern.SIMPLE_MONTH_PATTERN);
        }

        String version = LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_FORMATTER);
        //计算增量的pos交易
//        String tableName = PREFIX_TABLE_NAME + "after_" + thisMoth;
        String tableName = PREFIX_TABLE_NAME + thisMoth;
        String tempTableName = PREFIX_TABLE_NAME_TEMP + thisMoth;

        int batchSize = 20;
        TransactionTemplate template = new TransactionTemplate(platformTransactionManager);
        template.execute(status -> {
            //创建临时表
            baseMapper.createTemporaryShdTable(tempTableName);

            //查询pos交易
            Cursor<ShdTradeAmtVO> kxsUserTrades = baseMapper.getUserTradeList(tableName);
            for (ShdTradeAmtVO kxsUserTrade : kxsUserTrades) {
                ShdTradeAmtVO shdTradeAmtVO = baseMapper.getTempShdTableData(tempTableName, kxsUserTrade.getUserId());
                if (shdTradeAmtVO == null) {
                    shdTradeAmtVO = new ShdTradeAmtVO();
                    shdTradeAmtVO.setUserId(kxsUserTrade.getUserId());
                    shdTradeAmtVO.setPosAmt(kxsUserTrade.getPosAmt());
                    baseMapper.insertTempShdTableData(tempTableName, shdTradeAmtVO);
                } else {
                    shdTradeAmtVO.setPosAmt(shdTradeAmtVO.getPosAmt());
                    baseMapper.updateTempShdTableData(tempTableName, shdTradeAmtVO);
                }

            }
            //查询lkb交易
            Cursor<KxsLkbTrade> lkbTrades = kxsLkbTradeMapper.getUserTradeMonthList(thisMoth);
            for (KxsLkbTrade lkbTrade : lkbTrades) {
                ShdTradeAmtVO shdTradeAmtVO = baseMapper.getTempShdTableData(tempTableName, lkbTrade.getUserId());
                if (shdTradeAmtVO == null) {
                    shdTradeAmtVO = new ShdTradeAmtVO();
                    shdTradeAmtVO.setUserId(lkbTrade.getUserId());
                    shdTradeAmtVO.setLkbAmt(lkbTrade.getTradeAmt());
                    //活动交易 * 4加入
                    if (lkbTrade.getActTradeAmt() != null) {
                        shdTradeAmtVO.setLkbActAmt(lkbTrade.getActTradeAmt().multiply(BigDecimal.valueOf(4)));
                    }
                    baseMapper.insertTempShdTableData(tempTableName, shdTradeAmtVO);
                } else {
                    shdTradeAmtVO.setLkbAmt(lkbTrade.getTradeAmt());
                    //活动交易 * 4加入
                    if (lkbTrade.getActTradeAmt() != null) {
                        shdTradeAmtVO.setLkbActAmt(lkbTrade.getActTradeAmt().multiply(BigDecimal.valueOf(4)));
                    }
                    baseMapper.updateTempShdTableData(tempTableName, shdTradeAmtVO);
                }
            }
            //查询广电交易数据
            Cursor<KxsUserActTrade> kxsUserActTrades = kxsUserActTradeMapper.getUserTradeMonthList(thisMoth);
            for (KxsUserActTrade kxsUserActTrade : kxsUserActTrades) {
                //总激活数
                int actNum = kxsUserActTrade.getActNum();
                //查询注销的广电卡
                KxsUserLogoutTrade kxsUserLogoutTrade = kxsUserLogoutTradeMapper.selectOne(Wrappers.<KxsUserLogoutTrade>lambdaQuery()
                        .eq(KxsUserLogoutTrade::getUserId, kxsUserActTrade.getUserId())
                        .eq(KxsUserLogoutTrade::getTotalType, TotalTypeEnum.TEAM.getType()).last("limit 1"));
                //总激活数 减去注销的卡 = 实际激活总数
                if (kxsUserLogoutTrade != null) {
                    actNum = actNum - kxsUserLogoutTrade.getLogoutNum();
                }
                ShdTradeAmtVO shdTradeAmtVO = baseMapper.getTempShdTableData(tempTableName, kxsUserActTrade.getUserId());
                if (shdTradeAmtVO == null) {
                    shdTradeAmtVO = new ShdTradeAmtVO();
                    shdTradeAmtVO.setUserId(kxsUserActTrade.getUserId());
                    //广电卡 * 10000加入
                    shdTradeAmtVO.setGdAmt(NumberUtil.mul(actNum, CommonConstants.GD_CARDINAL_NUMBER));
                    baseMapper.insertTempShdTableData(tempTableName, shdTradeAmtVO);
                } else {
                    //广电卡 * 10000加入
                    shdTradeAmtVO.setGdAmt(NumberUtil.mul(actNum, CommonConstants.GD_CARDINAL_NUMBER));
                    baseMapper.updateTempShdTableData(tempTableName, shdTradeAmtVO);
                }
            }

            Cursor<ShdTradeAmtVO> shdTradeAmtVOList = baseMapper.getTempShdTableList(tempTableName);
            List<IntegralStatDTO> batch = new ArrayList<>();
            for (ShdTradeAmtVO kxsUserTrade : shdTradeAmtVOList) {
                //pos交易额 + 来客吧非活动交易额
                BigDecimal totalAmount = BigDecimal.ZERO;
                if (kxsUserTrade.getPosAmt() != null) {
                    totalAmount = totalAmount.add(kxsUserTrade.getPosAmt());
                }
                if (kxsUserTrade.getLkbAmt() != null) {
                    totalAmount = totalAmount.add(kxsUserTrade.getLkbAmt());
                }
                if (kxsUserTrade.getGdAmt() != null) {
                    totalAmount = totalAmount.add(kxsUserTrade.getGdAmt());
                }
                if (kxsUserTrade.getLkbActAmt() != null) {
                    totalAmount = totalAmount.add(kxsUserTrade.getLkbActAmt());
                }
                if (totalAmount.compareTo(CommonConstants.MAX_TOTAL_AMT) >= 0) {
                    IntegralStatDTO integralStatDTO = new IntegralStatDTO();
                    integralStatDTO.setTradeMonth(thisMoth);
                    integralStatDTO.setUserId(Long.valueOf(kxsUserTrade.getUserId()));
                    integralStatDTO.setTotalAmount(totalAmount);
                    integralStatDTO.setVersion(Long.valueOf(version));
                    batch.add(integralStatDTO);
                    log.info("用户{}交易额达标：{}", kxsUserTrade.getUserId(), totalAmount);
                }
                if (batch.size() >= batchSize) {
                    remoteKxsUserService.integralStat(batch, SecurityConstants.FROM_IN);
                    batch.clear();
                }
            }
            // 处理最后一批数据
            if (!batch.isEmpty()) {
                remoteKxsUserService.integralStat(batch, SecurityConstants.FROM_IN);
            }
            return null;
        });

        baseMapper.removeTempTable(tempTableName);
    }

    @Override
    public BigDecimal getStatAmount(String month) {
        //拼接表名
        String tableName = PREFIX_TABLE_NAME + month;
        return baseMapper.getStatAmount(tableName);
    }

    @Override
    public R getUserStatByDayOrMonth(StatUserGetUserStatByDayOrMonthDTO param) {
        Long userId = param.getUserId();
        Integer type = param.getType();
        Integer totalType = param.getTotalType();
        LocalDate now = LocalDate.now();
        List<String> times = new ArrayList<>();
        List<String> lastMonthTimes = null;
        if (type == 1) {
            //获取今日月份 用以校验是否跨越月份
            int toDayMonth = now.getMonthValue();
            //近七日
            for (int i = 0; i < 7; i++) {
                // 计算每一天的日期
                LocalDate currentDay = now.minusDays(i);
                // 将LocalDate转换为字符串 yyyyMMdd  获取到所需查询日期
                String currentDateString = LocalDateTimeUtil.format(currentDay, DatePattern.PURE_DATE_PATTERN);
                //获取当前日的月份值
                int monthValue = now.getMonthValue();//判断今日月份值与当前查询日月份是否一致
                if (toDayMonth == monthValue) {
                    //一致加入正常查询序列
                    times.add(currentDateString);
                } else {
                    //不一致构造加入二次查询序列
                    lastMonthTimes = new ArrayList<>();
                    lastMonthTimes.add(currentDateString);
                }
            }
            //开始查询   该方法整合全部查询
            StatUserGetUserStatByDayOrMonthVO statUserGetUserStatByDayOrMonthVO = getStatUserGetUserStatByDayOrMonthVO(userId, now, times, lastMonthTimes, type, totalType);
            return R.ok(statUserGetUserStatByDayOrMonthVO);
        } else if (type == 2) {
            //近半年
            for (int i = 0; i < 6; i++) {
                // 计算过去半年每月月份
                LocalDate currentDay = now.minusMonths(i);
                // 将LocalDate转换为字符串
                String currentDateString = LocalDateTimeUtil.format(currentDay, DatePattern.SIMPLE_MONTH_PATTERN);
                times.add(currentDateString);
            }
            StatUserGetUserStatByDayOrMonthVO statUserGetUserStatByDayOrMonthVO = getStatUserGetUserStatByDayOrMonthVO(userId, now, times, lastMonthTimes, type, totalType);
            return R.ok(statUserGetUserStatByDayOrMonthVO);
        } else {
            return R.failed("类型错误");
        }
    }

    @Override
    public R getHomeAmout(Long userId) {
        LocalDate now = LocalDate.now();
        String month = LocalDateTimeUtil.format(now, DatePattern.SIMPLE_MONTH_PATTERN);
        String today = LocalDateTimeUtil.format(now, DatePattern.PURE_DATE_PATTERN);
        //拼接表名
        String tableName = PREFIX_TABLE_NAME + month;
////        一次性查询全部数据 已弃用
//        StatUserGetHomeAmoutVO statUserGetHomeAmoutVO1 = baseMapper.getHomeAmout(userId,tableName,date,month);
        //今日交易额
        StatUserGetHomeAmoutVO statUserGetHomeAmoutVO = new StatUserGetHomeAmoutVO();

        //获取团队日总交易额
        BigDecimal amountToDay = statUserGetHomeAmoutVO.getAmountToDay();
        amountToDay = getAmountToDayOrMonth(userId, today, tableName, amountToDay, 1);
        statUserGetHomeAmoutVO.setAmountToDay(amountToDay);

        //获取团队月总交易额
        BigDecimal amountMonth = statUserGetHomeAmoutVO.getAmountMonth();
        amountMonth = getAmountToDayOrMonth(userId, month, tableName, amountMonth, 2);
        statUserGetHomeAmoutVO.setAmountMonth(amountMonth);

        //获取今日新增用户
        Integer userAddToDay = statUserGetHomeAmoutVO.getUserAddToDay();
        List<String> todayList = Collections.singletonList(today);
        List<TrendTimesVO> userAddTrendToday = kxsUserNewTradeMapper.getUserAddTrend(userId, todayList, 1, 1);
        for (TrendTimesVO trendTimesVO : userAddTrendToday) {
            userAddToDay += trendTimesVO.getTotal();
        }
        statUserGetHomeAmoutVO.setUserAddToDay(userAddToDay);

        //获取本月新增用户
        Integer userAddMonth = statUserGetHomeAmoutVO.getUserAddMonth();
        List<String> monthList = Collections.singletonList(month);
        List<TrendTimesVO> userAddTrendMonth = kxsUserNewTradeMapper.getUserAddTrend(userId, monthList, 2, 1);
        for (TrendTimesVO trendTimesVO : userAddTrendMonth) {
            userAddMonth += trendTimesVO.getTotal();
        }
        statUserGetHomeAmoutVO.setUserAddMonth(userAddMonth);

        //获取今日新增商户
        Integer merchantAddToDay = statUserGetHomeAmoutVO.getMerchantAddToDay();
        List<TrendTimesVO> userActListByDay = kxsUserActTradeMapper.getUserActListByDayOrMonth(monthList, userId, null, 1, 1);
        for (TrendTimesVO trendTimesVO : userActListByDay) {
            merchantAddToDay += trendTimesVO.getTotal();
        }
        statUserGetHomeAmoutVO.setMerchantAddToDay(merchantAddToDay);

        //获取本月新增商户
        Integer merchantAddMonth = statUserGetHomeAmoutVO.getMerchantAddMonth();
        List<TrendTimesVO> userActListByMonth = kxsUserActTradeMapper.getUserActListByDayOrMonth(monthList, userId, null, 2, 1);
        for (TrendTimesVO trendTimesVO : userActListByMonth) {
            merchantAddMonth += trendTimesVO.getTotal();
        }
        statUserGetHomeAmoutVO.setMerchantAddMonth(merchantAddMonth);
        return R.ok(statUserGetHomeAmoutVO);
    }

    @Override
    public R getMyTrade(StatUserGetMyTradeDTO param) {
        Long userId = SecurityUtils.getUser().getId();
        param.setUserId(userId);
        String month = param.getMonth();
        Integer type = param.getType();
        //拼接表名
        String tableName = CommonConstants.USER_TABLE_PREFIX + param.getMonth();
        StatUserGetMyTradeVO statUserGetMyTradeVO = new StatUserGetMyTradeVO();
        KxsUserTrade kxsUserPosTrade = new KxsUserTrade();
        //获取pos交易额
        try {
            //此处存在查询的月份不在统计范围,找不到表的错误,直接包裹跳过视为当月无交易
            kxsUserPosTrade = baseMapper.getMyPosOrCloudTrade(param, tableName, 0, userId, "");
        } catch (Exception e) {
            log.info(e.getMessage());
        }
        BigDecimal posDebitAmount = BigDecimal.ZERO;
        BigDecimal posCreditAmount = BigDecimal.ZERO;
        if (kxsUserPosTrade != null) {
            BigDecimal proBDirectTradeAmt = kxsUserPosTrade.getProBDirectTradeAmt();//稳定期B贷记卡
            BigDecimal proADirectTradeAmt = kxsUserPosTrade.getProADirectTradeAmt();//稳定期A贷记卡
            BigDecimal proDirectTradeAmt = kxsUserPosTrade.getProDirectTradeAmt();//稳定期贷记卡
            BigDecimal helpDirectTradeAmt = kxsUserPosTrade.getHelpDirectTradeAmt();//扶持期贷记卡交易额


            BigDecimal proBDebitTradeAmt = kxsUserPosTrade.getProBDebitTradeAmt();//稳定期B借记卡
            BigDecimal proADebitTradeAmt = kxsUserPosTrade.getProADebitTradeAmt();//稳定期A借记卡
            BigDecimal proDebitTradeAmt = kxsUserPosTrade.getProDebitTradeAmt();//稳定期借记卡
            BigDecimal helpDebitTradeAmt = kxsUserPosTrade.getHelpDebitTradeAmt();//扶持期借记卡

            //pos借记卡
            posDebitAmount = posDebitAmount.add(proBDebitTradeAmt).add(proADebitTradeAmt).add(proDebitTradeAmt).add(helpDebitTradeAmt);
            //贷记卡
            posCreditAmount = posCreditAmount.add(proBDirectTradeAmt).add(proADirectTradeAmt).add(proDirectTradeAmt).add(helpDirectTradeAmt);
        }
        statUserGetMyTradeVO.setPosDebitAmount(posDebitAmount);//Pos借记卡
        statUserGetMyTradeVO.setPosCreditAmount(posCreditAmount);//Pos贷记卡
        KxsUserTrade kxsUserCloudTrade = new KxsUserTrade();
        //获取云闪付交易额
        try {
            //此处存在查询的月份不在统计范围,找不到表的错误,直接包裹跳过视为当月无交易
            kxsUserCloudTrade = baseMapper.getMyPosOrCloudTrade(param, tableName, 1, userId, "");
        } catch (Exception e) {
            log.info(e.getMessage());
        }
        BigDecimal cloudAmount = BigDecimal.ZERO;
        if (kxsUserCloudTrade != null) {
            cloudAmount = cloudAmount.add(kxsUserCloudTrade.getProBDirectTradeAmt())
                    .add(kxsUserCloudTrade.getProADirectTradeAmt())
                    .add(kxsUserCloudTrade.getProDirectTradeAmt())
                    .add(kxsUserCloudTrade.getHelpDirectTradeAmt())
                    .add(kxsUserCloudTrade.getProBDebitTradeAmt())
                    .add(kxsUserCloudTrade.getProADebitTradeAmt())
                    .add(kxsUserCloudTrade.getProDebitTradeAmt())
                    .add(kxsUserCloudTrade.getHelpDebitTradeAmt());
        }
        statUserGetMyTradeVO.setCloudAmunt(cloudAmount);//云闪付


        //助力宝交易额
        TotalTradeAmtVO totalTradeAmtVO = kxsZlbTradeMapper.getZlbTrade(userId, month, 2, type);
        BigDecimal zlbAmt = BigDecimal.ZERO;
        if (totalTradeAmtVO != null) {
            zlbAmt = totalTradeAmtVO.getZlbAmt();
        }
        statUserGetMyTradeVO.setZlbAmount(zlbAmt);//助力宝


        totalTradeAmtVO = kxsLkbTradeMapper.getLkbTrade(userId, month, 2, type);
        BigDecimal lkbActAmt = BigDecimal.ZERO;
        BigDecimal lkbAmt = BigDecimal.ZERO;
        if (totalTradeAmtVO != null) {
            lkbActAmt = totalTradeAmtVO.getLkbActAmt();
            lkbAmt = totalTradeAmtVO.getLkbAmt();
        }
        statUserGetMyTradeVO.setLkbActivityAmount(lkbActAmt);//来客吧活动
        statUserGetMyTradeVO.setLkbAmount(lkbAmt);//来客吧非活动


        totalTradeAmtVO = kxsUserGdTradeMapper.getGdTrade(userId, month, 2, type);
        BigDecimal gdAmount = BigDecimal.ZERO;
        if (totalTradeAmtVO != null) {
            gdAmount = totalTradeAmtVO.getGdAmount();
        }
        statUserGetMyTradeVO.setGdTelephoneCharge(gdAmount);//广电话费

        //广电交易额
        totalTradeAmtVO = kxsUserGdTradeMapper.getGdActCount(userId, month, 2, type);
        BigDecimal gdActivityAmount = BigDecimal.ZERO;
        if (totalTradeAmtVO != null) {
            Integer gdCount = totalTradeAmtVO.getGdCount();
            //广电激活量 * 10000
            gdActivityAmount = gdActivityAmount.add(new BigDecimal(gdCount * 10000));
        }
        statUserGetMyTradeVO.setGdActivityAmount(gdActivityAmount);//广电活动

        BigDecimal totalAmount = BigDecimal.ZERO;
        totalAmount = totalAmount.add(posDebitAmount).add(posCreditAmount).add(cloudAmount).add(zlbAmt).add(lkbActAmt).add(lkbAmt).add(gdAmount).add(gdActivityAmount);
        statUserGetMyTradeVO.setTotalAmount(totalAmount);//总交易

        //获取指定月新增用户
        Integer userAddMonth = 0;
        List<String> monthList = Arrays.asList(month);
        List<TrendTimesVO> userAddTrendMonth = kxsUserNewTradeMapper.getUserAddTrend(userId, monthList, 2, type);
        for (TrendTimesVO trendTimesVO : userAddTrendMonth) {
            userAddMonth += trendTimesVO.getTotal();
        }
        statUserGetMyTradeVO.setUserAddCount(userAddMonth);//新增用户


        Integer totalUserCount = kxsUserNewTradeMapper.getUserAllTrend(userId, type);
        statUserGetMyTradeVO.setTotalUserCount(totalUserCount != null ? totalUserCount : 0);//总用户

        //获取累计全部激活商户
        Integer merchantAddMonth = kxsUserActTradeMapper.getUserActListByAll(userId, type, 1, 3, null);
        statUserGetMyTradeVO.setActivateMerchantCount(merchantAddMonth);//商户总激活

        //获取累计全部激活码牌
        Integer signCount = kxsLkbActTradeMapper.getSignCount(userId, type);
        statUserGetMyTradeVO.setActivateSignCount(signCount != null ? signCount : 0);//码牌

        //获取
        Integer simCount = kxsUserActTradeMapper.getUserActListByAll(userId, type, 2, 2, Integer.valueOf(month));
        statUserGetMyTradeVO.setActivateSIMCount(simCount != null ? simCount : 0);//存量激活sim卡
        Integer simToMonthCount = kxsUserActTradeMapper.getUserActListByAll(userId, type, 2, 1, Integer.valueOf(month));
        statUserGetMyTradeVO.setActivateSIMToMonthCount(simToMonthCount != null ? simToMonthCount : 0);//当月
        statUserGetMyTradeVO.setType(param.getType());
        return R.ok(statUserGetMyTradeVO);
    }

    @Override
    public R getUserTradeStatList(StatUserGetUserTradeListDTO param) {
        String month = param.getMonth();//查询月
        Integer totalType = param.getTotalType();//查询类型 0个人 1团队
        Long userId = param.getUserId();
        Integer getType = param.getGetType();//获取类型 1获取月 2获取半年
        Integer tradeType = param.getTradeType();//1获取增量 2获取存量 3获取全部
        LocalDate now = LocalDate.now();
        String tableName = "";
        List<String> times = new ArrayList<>();
        if (tradeType.equals(3)) {//获取全部
            tableName = PREFIX_TABLE_NAME; //全部
            if (getType.equals(2)) {//查询近半年
                ArrayList<StatUserGetUserTradeStatListVO> statUserGetUserTradeStatListVOS = getStatUserGetUserTradeStatListVOSByMonth(month, totalType, userId, getType, now, times, tableName, tradeType);
                return R.ok(statUserGetUserTradeStatListVOS);
            } else if (getType.equals(1)) {//查询月详细
                ArrayList<StatUserGetUserTradeStatListVO> statUserGetUserTradeStatListVOS = getUserGetUserTradeStatListVOSByDay(month, totalType, userId, getType, now, times, tableName, tradeType);
                return R.ok(statUserGetUserTradeStatListVOS);
            }
        } else if (tradeType.equals(2)) {
            tableName = PREFIX_TABLE_NAME_BEFORE; //存量
            if (getType.equals(2)) {//查询近半年
                ArrayList<StatUserGetUserTradeStatListVO> statUserGetUserTradeStatListVOS = getStatUserGetUserTradeStatListVOSByMonth(month, totalType, userId, getType, now, times, tableName, tradeType);
                return R.ok(statUserGetUserTradeStatListVOS);
            } else if (getType.equals(1)) {//查询月详细
                ArrayList<StatUserGetUserTradeStatListVO> statUserGetUserTradeStatListVOS = getUserGetUserTradeStatListVOSByDay(month, totalType, userId, getType, now, times, tableName, tradeType);
                return R.ok(statUserGetUserTradeStatListVOS);
            }
        } else if (tradeType.equals(1)) {
            tableName = PREFIX_TABLE_NAME_AFTER; //增量
            if (getType.equals(2)) {//查询近半年
                ArrayList<StatUserGetUserTradeStatListVO> statUserGetUserTradeStatListVOS = getStatUserGetUserTradeStatListVOSByMonth(month, totalType, userId, getType, now, times, tableName, tradeType);
                return R.ok(statUserGetUserTradeStatListVOS);
            } else if (getType.equals(1)) {//查询月详细
                ArrayList<StatUserGetUserTradeStatListVO> statUserGetUserTradeStatListVOS = getUserGetUserTradeStatListVOSByDay(month, totalType, userId, getType, now, times, tableName, tradeType);
                return R.ok(statUserGetUserTradeStatListVOS);
            }
        }
            return R.ok();

    }

    @Override
    public R getTradeDetail(StatUserGetTradeDetailDTO param) {
        Integer totalType = param.getTotalType();//0:个人 1:计奖
        Integer month = param.getDate();//该参数有效获取月份格式yyyyMM   日格式yyyyMMdd
        Integer getType = param.getGetType();// 1获取日详情 2获取月详情
        Integer tradeType = param.getTradeType();//1获取增量 2获取存量 3获取全部
        Long userId = param.getUserId();//用户id
        if(userId == null || userId == 0){
            userId = SecurityUtils.getUser().getId();
        }
        Integer brandId = param.getBrandId();//品牌id

        String tableName;
        switch (tradeType){
            case 1 -> tableName = CommonConstants.USER_TABLE_AFTER_PREFIX + month;
            case 2 -> tableName = CommonConstants.USER_TABLE_BEFORE_PREFIX + month;
            case 3 -> tableName = CommonConstants.USER_TABLE_PREFIX + month;
            default ->  throw new GlobalCustomerException("参数错误");
        }



        StatUserGetTradeDetailVO statUserGetTradeDetailVO = new StatUserGetTradeDetailVO();
        statUserGetTradeDetailVO.setDate(month);//交易时间
        statUserGetTradeDetailVO.setBrandId(brandId);//品牌

        //扶持期
        StatUserTradeVo statUserTradeVo = new StatUserTradeVo();
        //稳定期
        StatUserTradeVo proStatUserTradeVo = new StatUserTradeVo();
        //稳定期A
        StatUserTradeVo proAstatUserTradeVo = new StatUserTradeVo();
        //稳定期B
        StatUserTradeVo proBstatUserTradeVo = new StatUserTradeVo();

        //pos交易
        KxsUserTrade kxsUserTradePos = baseMapper.getAllUserTrderSum(userId, month, getType, 0, brandId, totalType, tableName);
        if (kxsUserTradePos != null) {
            statUserTradeVo.setDirectTradeAmt(kxsUserTradePos.getHelpDirectTradeAmt());//扶持期贷记卡
            statUserTradeVo.setDebitTradeAmt(kxsUserTradePos.getHelpDebitTradeAmt());//扶持期借记卡
            statUserTradeVo.setDebitCapTradeAmt(kxsUserTradePos.getHelpDebitCapTradeAmt());//扶持期借记卡封顶交易额
            statUserTradeVo.setDebitCapNum(kxsUserTradePos.getHelpDebitCapNum());//扶持期借记卡封顶交易笔数
            BigDecimal helpNotCapTrade = kxsUserTradePos.getHelpDebitTradeAmt().subtract(kxsUserTradePos.getHelpDebitCapTradeAmt());//非封顶交易额
            statUserTradeVo.setCloudTrade(helpNotCapTrade);//扶持期非封顶借记卡交易额
            statUserTradeVo.setPosTrade(kxsUserTradePos.getHelpDirectTradeAmt().add(kxsUserTradePos.getHelpDebitTradeAmt()));//交易总和

            proStatUserTradeVo.setDirectTradeAmt(kxsUserTradePos.getProDirectTradeAmt());//稳定期贷记卡
            proStatUserTradeVo.setDebitTradeAmt(kxsUserTradePos.getProDebitTradeAmt());//稳定期借记卡
            proStatUserTradeVo.setDebitCapTradeAmt(kxsUserTradePos.getProDebitCapTradeAmt());//稳定期借记卡封顶交易额
            proStatUserTradeVo.setDebitCapNum(kxsUserTradePos.getProDebitCapNum());//稳定期借记卡封顶交易笔数
            BigDecimal proNotCapTrade = kxsUserTradePos.getProDebitTradeAmt().subtract(kxsUserTradePos.getProDebitCapTradeAmt());//非封顶交易额
            proStatUserTradeVo.setCloudTrade(proNotCapTrade);//稳定期非封顶借记卡交易额
            proStatUserTradeVo.setPosTrade(kxsUserTradePos.getProDirectTradeAmt().add(kxsUserTradePos.getProDebitTradeAmt()));//交易总和

            proAstatUserTradeVo.setDirectTradeAmt(kxsUserTradePos.getProADirectTradeAmt());//稳A贷记
            proAstatUserTradeVo.setDebitTradeAmt(kxsUserTradePos.getProADebitTradeAmt());//稳A借记
            proAstatUserTradeVo.setDebitCapTradeAmt(kxsUserTradePos.getProADebitCapTradeAmt());//稳定期A借记卡封顶交易额
            proAstatUserTradeVo.setDebitCapNum(kxsUserTradePos.getProADebitCapNum());//稳定期A借记卡封顶交易笔数
            BigDecimal proANotCapTrade = kxsUserTradePos.getProADebitTradeAmt().subtract(kxsUserTradePos.getProADebitCapTradeAmt());//非封顶交易额
            proAstatUserTradeVo.setCloudTrade(proANotCapTrade);//稳定期b非封顶借记卡交易额
            proAstatUserTradeVo.setPosTrade(kxsUserTradePos.getProADirectTradeAmt().add(kxsUserTradePos.getProADebitTradeAmt()));//交易总和

            proBstatUserTradeVo.setDirectTradeAmt(kxsUserTradePos.getProBDirectTradeAmt());//稳定期B借记卡
            proBstatUserTradeVo.setDebitTradeAmt(kxsUserTradePos.getProBDebitTradeAmt());//稳定期B贷记卡
            proBstatUserTradeVo.setDebitCapTradeAmt(kxsUserTradePos.getProBDebitCapTradeAmt());//稳定期B借记卡封顶交易额
            proBstatUserTradeVo.setDebitCapNum(kxsUserTradePos.getProBDebitCapNum());//稳定期B借记卡封顶交易笔数
            BigDecimal proBNotCapTrade = kxsUserTradePos.getProBDebitTradeAmt().subtract(kxsUserTradePos.getProBDebitCapTradeAmt());//稳定期b非封顶交易额
            proBstatUserTradeVo.setCloudTrade(proBNotCapTrade);//稳定期b非封顶借记卡交易额
            proBstatUserTradeVo.setPosTrade(kxsUserTradePos.getProBDirectTradeAmt().add(kxsUserTradePos.getProBDebitTradeAmt()));//交易总和
        }
        //云闪付
        KxsUserTrade kxsUserTradeCloud = baseMapper.getAllUserTrderSum(userId, month, getType, 1, brandId, totalType, tableName);
        if (kxsUserTradeCloud != null) {
            BigDecimal helpTrade = kxsUserTradeCloud.getHelpDebitCapTradeAmt().add(kxsUserTradeCloud.getHelpDirectTradeAmt());//计算扶持期云闪付交易额
            statUserTradeVo.setCloudTrade(helpTrade);//扶持期云闪付交易额

            BigDecimal proTrade = kxsUserTradeCloud.getProDebitCapTradeAmt().add(kxsUserTradeCloud.getProDirectTradeAmt());//计算稳定期云闪付交易额
            proStatUserTradeVo.setCloudTrade(proTrade);//稳定期云闪付交易额

            BigDecimal proATrade = kxsUserTradeCloud.getProADebitCapTradeAmt().add(kxsUserTradeCloud.getProADirectTradeAmt());//计算稳定期b云闪付交易额
            proAstatUserTradeVo.setCloudTrade(proATrade);//稳定期A云闪付交易额

            BigDecimal proBTrade = kxsUserTradeCloud.getProBDebitCapTradeAmt().add(kxsUserTradeCloud.getProBDirectTradeAmt());//计算稳定期a云闪付交易额
            proBstatUserTradeVo.setCloudTrade(proBTrade);//稳定期B云闪付交易额
        }
        statUserGetTradeDetailVO.setHelpDirectTradeAmt(statUserTradeVo);
        statUserGetTradeDetailVO.setProDirectTradeAmt(proStatUserTradeVo);
        statUserGetTradeDetailVO.setProADirectTradeAmt(proAstatUserTradeVo);
        statUserGetTradeDetailVO.setProBDirectTradeAmt(proBstatUserTradeVo);

        return R.ok(statUserGetTradeDetailVO);
    }

    private ArrayList<StatUserGetUserTradeStatListVO> getUserGetUserTradeStatListVOSByDay(String month, Integer totalType, Long userId, Integer getType, LocalDate now, List<String> times, String tableName, Integer tradeType) {
        //校验时间格式是yyyyMM
        AssertUtil.isyyyyMM(month);
        //判断month是否是本月  否则获取月份中全部日日期
        int year = Integer.parseInt(month.substring(0, 4));
        int monthOfYear = Integer.parseInt(month.substring(4, 6));
        // 判断给定的月份字符串是否表示当前月份
        boolean isCurrentMonth = year == now.getYear() && monthOfYear == now.getMonthValue();
        // 如果是当前月份，则生成本月到今天的日期字符串
        if (isCurrentMonth) {
            LocalDate firstDayOfMonth = now.withDayOfMonth(1);
            for (LocalDate date = firstDayOfMonth; !date.isAfter(now); date = date.plusDays(1)) {
                times.add(date.format(DateTimeFormatter.ofPattern("yyyyMMdd")));
            }
        } else {
            // 如果不是当前月份，则生成整个月的日期字符串
            LocalDate firstDayOfMonth = LocalDate.of(year, monthOfYear, 1);
            int daysInMonth = firstDayOfMonth.lengthOfMonth();
            for (int day = 1; day <= daysInMonth; day++) {
                LocalDate date = firstDayOfMonth.withDayOfMonth(day);
                times.add(date.format(DateTimeFormatter.ofPattern("yyyyMMdd")));
            }
        }
        //拼接表名
        String lastTableName = tableName + month;
        ArrayList<StatUserGetUserTradeStatListVO> statUserGetUserTradeStatListVOS = new ArrayList<>();
        //构造查询Dto
        StatUserGetMyTradeDTO statUserGetMyTradeDTO = new StatUserGetMyTradeDTO();
        statUserGetMyTradeDTO.setMonth(month);
        statUserGetMyTradeDTO.setType(totalType);
        for (int i = times.size() - 1; i >= 0; i--) {
            String time = times.get(i);
            //查询交易额
            KxsUserTrade myPosTrade = null;
            try {
                //此处存在不存在表  跳过报错视为无数据
                myPosTrade = baseMapper.getMyPosOrCloudTrade(statUserGetMyTradeDTO, lastTableName, 0, userId, time);
            } catch (Exception e) {
                log.info(e.getMessage());
            }
            if (myPosTrade == null) {
                myPosTrade = new KxsUserTrade();
            }
            StatUserGetUserTradeStatListVO statUserGetUserTradeStatListVO = getMonthTrade(totalType, userId, getType, statUserGetMyTradeDTO, myPosTrade, month, time, tableName, tradeType);
            statUserGetUserTradeStatListVO.setTime(time);
            statUserGetUserTradeStatListVOS.add(statUserGetUserTradeStatListVO);
        }
        return statUserGetUserTradeStatListVOS;

    }

    private ArrayList<StatUserGetUserTradeStatListVO> getStatUserGetUserTradeStatListVOSByMonth(String month, Integer totalType, Long userId, Integer getType, LocalDate now, List<String> times, String tableName, Integer tradeType) {
        //近半年
        for (int i = 0; i < 6; i++) {
            // 计算过去半年每月月份
            LocalDate currentDay = now.minusMonths(i);
            // 将LocalDate转换为字符串
            String currentDateString = LocalDateTimeUtil.format(currentDay, DatePattern.SIMPLE_MONTH_PATTERN);
            times.add(currentDateString);
        }
        //获取交易额
        //构造查询Dto
        StatUserGetMyTradeDTO statUserGetMyTradeDTO = new StatUserGetMyTradeDTO();
        statUserGetMyTradeDTO.setMonth(month);
        statUserGetMyTradeDTO.setType(totalType);
        ArrayList<StatUserGetUserTradeStatListVO> statUserGetUserTradeStatListVOS = new ArrayList<>();
        //查询进半年需要循环查询不同的表
        for (int i = times.size() - 1; i >= 0; i--) {
            String time = times.get(i);
            try {
                //拼接表名  因有可能查询不存在的表导致报错我们try包裹视为无数据
                String lastTableName = tableName + time;
                //查询交易额
                KxsUserTrade myPosTrade = baseMapper.getMyPosOrCloudTrade(statUserGetMyTradeDTO, lastTableName, 0, userId, "");
                if (myPosTrade == null) {
                    myPosTrade = new KxsUserTrade();
                }
                StatUserGetUserTradeStatListVO statUserGetUserTradeStatListVO = getMonthTrade(totalType, userId, getType, statUserGetMyTradeDTO, myPosTrade, month, time, tableName, tradeType);
                statUserGetUserTradeStatListVO.setTime(time);
                statUserGetUserTradeStatListVOS.add(statUserGetUserTradeStatListVO);
            } catch (Exception e) {
                log.info(e.getMessage());
            }
        }
        return statUserGetUserTradeStatListVOS;
    }

    private StatUserGetUserTradeStatListVO getMonthTrade(Integer totalType, Long userId, Integer getType, StatUserGetMyTradeDTO statUserGetMyTradeDTO, KxsUserTrade kxsUserTrade, String month, String date, String tableName, Integer tradeType) {
        BigDecimal helpDirectTradeAmt = kxsUserTrade.getHelpDirectTradeAmt() == null ? BigDecimal.ZERO : kxsUserTrade.getHelpDirectTradeAmt();//扶贷
        BigDecimal helpDebitTradeAmt = kxsUserTrade.getHelpDebitTradeAmt() == null ? BigDecimal.ZERO : kxsUserTrade.getHelpDebitTradeAmt();//扶借

        BigDecimal proDirectTradeAmt = kxsUserTrade.getProDirectTradeAmt() == null ? BigDecimal.ZERO : kxsUserTrade.getProDirectTradeAmt();//稳贷
        BigDecimal proDebitTradeAmt = kxsUserTrade.getProDebitTradeAmt() == null ? BigDecimal.ZERO : kxsUserTrade.getProDebitTradeAmt();//稳借

        BigDecimal proADirectTradeAmt = kxsUserTrade.getProADirectTradeAmt() == null ? BigDecimal.ZERO : kxsUserTrade.getProADirectTradeAmt();//稳A贷
        BigDecimal proADebitTradeAmt = kxsUserTrade.getProADebitTradeAmt() == null ? BigDecimal.ZERO : kxsUserTrade.getProADebitTradeAmt();//稳A借

        BigDecimal proBDebitTradeAmt = kxsUserTrade.getProBDebitTradeAmt() == null ? BigDecimal.ZERO : kxsUserTrade.getProBDebitTradeAmt();//稳B借
        BigDecimal proBDirectTradeAmt = kxsUserTrade.getProBDirectTradeAmt() == null ? BigDecimal.ZERO : kxsUserTrade.getProBDirectTradeAmt();//稳B贷

        BigDecimal totalAmount = BigDecimal.ZERO;

        StatUserGetUserTradeStatListVO statUserGetUserTradeStatListVO = new StatUserGetUserTradeStatListVO();
        BigDecimal debitPos = helpDebitTradeAmt.add(proDebitTradeAmt).add(proADebitTradeAmt).add(proBDebitTradeAmt);
        BigDecimal diretPos = helpDirectTradeAmt.add(proDirectTradeAmt).add(proADirectTradeAmt).add(proBDirectTradeAmt);
        //pos机交易额
        statUserGetUserTradeStatListVO.setPosDebitAmount(debitPos);
        statUserGetUserTradeStatListVO.setPosCreditAmount(diretPos);
        totalAmount = totalAmount.add(debitPos).add(diretPos);
        //拼接表名
        tableName = tableName + month;
        KxsUserTrade myCloudTrade = null;
        try {
            //存在表不存在的月份,跳过报错视为无数据  查询云闪付
            myCloudTrade = baseMapper.getMyPosOrCloudTrade(statUserGetMyTradeDTO, tableName, 1, userId, getType == 1 ? date:null);
        } catch (Exception e) {
            log.info(e.getMessage());
        }
        if (myCloudTrade == null) {
            myCloudTrade = new KxsUserTrade();
        }
        BigDecimal helpDirectTradeAmtCloud = myCloudTrade.getHelpDirectTradeAmt() == null ? BigDecimal.ZERO : myCloudTrade.getHelpDirectTradeAmt();//扶贷
        BigDecimal helpDebitTradeAmtCloud = myCloudTrade.getHelpDebitTradeAmt() == null ? BigDecimal.ZERO : myCloudTrade.getHelpDebitTradeAmt();//扶借

        BigDecimal proDirectTradeAmtCloud = myCloudTrade.getProDirectTradeAmt() == null ? BigDecimal.ZERO : myCloudTrade.getProDirectTradeAmt();//稳贷
        BigDecimal proDebitTradeAmtCloud = myCloudTrade.getProDebitTradeAmt() == null ? BigDecimal.ZERO : myCloudTrade.getProDebitTradeAmt();//稳借

        BigDecimal proADirectTradeAmtCloud = myCloudTrade.getProADirectTradeAmt() == null ? BigDecimal.ZERO : myCloudTrade.getProADirectTradeAmt();//稳A贷
        BigDecimal proADebitTradeAmtCloud = myCloudTrade.getProADebitTradeAmt() == null ? BigDecimal.ZERO : myCloudTrade.getProADebitTradeAmt();//稳A借

        BigDecimal proBDebitTradeAmtCloud = myCloudTrade.getProBDebitTradeAmt() == null ? BigDecimal.ZERO : myCloudTrade.getProBDebitTradeAmt();//稳B借
        BigDecimal proBDirectTradeAmtCloud = myCloudTrade.getProBDirectTradeAmt() == null ? BigDecimal.ZERO : myCloudTrade.getProBDirectTradeAmt();//稳B贷
        BigDecimal posAmount = helpDirectTradeAmtCloud
                .add(helpDebitTradeAmtCloud)
                .add(proDirectTradeAmtCloud)
                .add(proDebitTradeAmtCloud)
                .add(proADirectTradeAmtCloud)
                .add(proADebitTradeAmtCloud)
                .add(proBDebitTradeAmtCloud)
                .add(proBDirectTradeAmtCloud);
        //云闪付交易额
        statUserGetUserTradeStatListVO.setCloudAmunt(posAmount);
        totalAmount = totalAmount.add(posAmount);

        if (!tradeType.equals(2)) {//存量不存在以下数据
            //助力宝交易额
            TotalTradeAmtVO TotalTradeAmtVO = kxsZlbTradeMapper.getZlbTrade(userId, String.valueOf(date), getType, totalType);
            TotalTradeAmtVO = TotalTradeAmtVO == null ? new TotalTradeAmtVO() : TotalTradeAmtVO;


            BigDecimal zlbAmt = TotalTradeAmtVO.getZlbAmt() == null ? BigDecimal.ZERO : TotalTradeAmtVO.getZlbAmt();
            statUserGetUserTradeStatListVO.setZlbAmount(zlbAmt);
            totalAmount = totalAmount.add(zlbAmt);

            //来客吧交易额
            TotalTradeAmtVO = kxsLkbTradeMapper.getLkbTrade(userId, String.valueOf(date), getType, totalType);
            TotalTradeAmtVO = TotalTradeAmtVO == null ? new TotalTradeAmtVO() : TotalTradeAmtVO;

            BigDecimal lkbActAmt = TotalTradeAmtVO.getLkbActAmt() == null ? BigDecimal.ZERO : TotalTradeAmtVO.getLkbActAmt();
            statUserGetUserTradeStatListVO.setLkbActivityAmount(lkbActAmt);
            totalAmount = totalAmount.add(lkbActAmt);


            BigDecimal lkbAmt = TotalTradeAmtVO.getLkbAmt() == null ? BigDecimal.ZERO : TotalTradeAmtVO.getLkbAmt();
            statUserGetUserTradeStatListVO.setLkbAmount(lkbAmt);
            totalAmount = totalAmount.add(lkbAmt);
            //广电话费
            TotalTradeAmtVO = kxsUserGdTradeMapper.getGdTrade(userId, String.valueOf(date), getType, totalType);
            TotalTradeAmtVO = TotalTradeAmtVO == null ? new TotalTradeAmtVO() : TotalTradeAmtVO;

            BigDecimal gdAmount = TotalTradeAmtVO.getGdAmount() == null ? BigDecimal.ZERO : TotalTradeAmtVO.getGdAmount();
            statUserGetUserTradeStatListVO.setGdTelephoneCharge(gdAmount);
            totalAmount = totalAmount.add(gdAmount);

            if (tradeType.equals(3)) {//广电获取全部
                //广电激活量
                if (getType == 1) {
                    TotalTradeAmtVO = kxsUserGdTradeMapper.getGdActCount(userId, String.valueOf(date), 3, totalType);
                } else {
                    TotalTradeAmtVO = kxsUserGdTradeMapper.getGdActCount(userId, String.valueOf(date), 4, totalType);
                }
                TotalTradeAmtVO = TotalTradeAmtVO == null ? new TotalTradeAmtVO() : TotalTradeAmtVO;

                BigDecimal gdActAmt = BigDecimal.valueOf(TotalTradeAmtVO.getGdCount() != null ? TotalTradeAmtVO.getGdCount() * 10000 : 0);
                statUserGetUserTradeStatListVO.setGdActivityAmount(gdActAmt);
            }
            if (tradeType.equals(1)) {//广电获取增量  只获取当前时间
                //广电激活量
                TotalTradeAmtVO = kxsUserGdTradeMapper.getGdActCount(userId, String.valueOf(date), getType, totalType);
                TotalTradeAmtVO = TotalTradeAmtVO == null ? new TotalTradeAmtVO() : TotalTradeAmtVO;

                BigDecimal gdActAmt = BigDecimal.valueOf(TotalTradeAmtVO.getGdCount() != null ? TotalTradeAmtVO.getGdCount() * 10000 : 0);
                statUserGetUserTradeStatListVO.setGdActivityAmount(gdActAmt);
            }
        }
        //总额
        statUserGetUserTradeStatListVO.setTotalAmount(totalAmount);

        //查询各品牌交易总额
        List<StatUserBrandTradeVO> statUserBrandTradeVOS = baseMapper.getStatUserBrandTradeVOS(userId,getType, tableName,totalType,date);
        statUserGetUserTradeStatListVO.setProductList(statUserBrandTradeVOS);
        return statUserGetUserTradeStatListVO;
    }

    private BigDecimal getAmountToDayOrMonth(Long userId, String date, String tableName, BigDecimal amount, int type) {
        //pos交易
        TotalTradeAmtVO totalTradeAmtVO = baseMapper.getPosTrade(userId, tableName, date, type);
        if (totalTradeAmtVO != null) {
            amount = amount.add(totalTradeAmtVO.getPosAmt());
        }
        //来客吧交易额
        totalTradeAmtVO = kxsLkbTradeMapper.getLkbTrade(userId, date, type, 1);
        if (totalTradeAmtVO != null) {
            amount = amount.add(totalTradeAmtVO.getLkbAmt());
            amount = amount.add(totalTradeAmtVO.getLkbActAmt());
        }
        //助力宝交易额
        totalTradeAmtVO = kxsZlbTradeMapper.getZlbTrade(userId, date, type, 1);
        if (totalTradeAmtVO != null) {
            amount = amount.add(totalTradeAmtVO.getZlbAmt());
        }
        //广电交易额
        totalTradeAmtVO = kxsUserGdTradeMapper.getGdActCount(userId, date, type, 1);
        if (totalTradeAmtVO != null) {
            Integer gdCount = totalTradeAmtVO.getGdCount();
            //广电激活量 * 10000
            amount = amount.add(new BigDecimal(gdCount * 10000));
        }
        //广电话费
        totalTradeAmtVO = kxsUserGdTradeMapper.getGdTrade(userId, date, type, 1);
        if (totalTradeAmtVO != null) {
            amount = amount.add(totalTradeAmtVO.getGdAmount());
        }
        return amount;
    }


    private StatUserGetUserStatByDayOrMonthVO getStatUserGetUserStatByDayOrMonthVO(Long userId, LocalDate now, List<String> times, List<String> lastMonthTimes, Integer type, Integer totalType) {
        StatUserGetUserStatByDayOrMonthVO statUserGetUserStatByDayOrMonthVO = new StatUserGetUserStatByDayOrMonthVO();
        /* ------ 交易趋势图 ------ */
        setTreadeTrend(userId, now, times, lastMonthTimes, statUserGetUserStatByDayOrMonthVO, type, totalType);
        /* ------ 交易百分比及总额 ------ */
        setTreadeTotalAndPercent(userId, times, lastMonthTimes, statUserGetUserStatByDayOrMonthVO, type, totalType);
        /* ------ 激活百分比及总额 ------ */
        setActTotalAndPercent(userId, times, lastMonthTimes, statUserGetUserStatByDayOrMonthVO, type, totalType);
        /* ------ 激活趋势图 ------ */
        setActTrend(userId, times, lastMonthTimes, statUserGetUserStatByDayOrMonthVO, type, totalType);
        /* ------ 新增用户趋势图 ------ */
        setUserAddTrend(userId, times, type, statUserGetUserStatByDayOrMonthVO, totalType);
        return statUserGetUserStatByDayOrMonthVO;
    }

    private void setUserAddTrend(Long userId, List<String> times, Integer type, StatUserGetUserStatByDayOrMonthVO statUserGetUserStatByDayOrMonthVO, Integer totalType) {
        TrendVO trendVO = new TrendVO();
        List<TrendTimesVO> trendTimesVOS = kxsUserNewTradeMapper.getUserAddTrend(userId, times, type, totalType);
        repZero(times, trendTimesVOS);
        trendVO.setName("all");
        trendVO.setTimes(trendTimesVOS);
        statUserGetUserStatByDayOrMonthVO.setUserAddTrend(trendVO);
    }

    private void setActTrend(Long userId, List<String> times, List<String> lastMonthTimes, StatUserGetUserStatByDayOrMonthVO statUserGetUserStatByDayOrMonthVO, Integer type, Integer totalType) {


        //查询用户全部激活根据日期分组
        List<TrendTimesVO> trendTimesActVOS = kxsUserActTradeMapper.getUserActListByDayOrMonth(times, userId, null, type, totalType);
        //判断是否二次查询
        if (lastMonthTimes != null) {
            List<TrendTimesVO> trendTimesActVOSLast = kxsUserActTradeMapper.getUserActListByDayOrMonth(lastMonthTimes, userId, null, type, totalType);
            trendTimesActVOS.addAll(trendTimesActVOSLast);
        }
        //查询用户全部激活量根据 日期以及品牌 分组
        List<TrendTimesVO> trendTimesActBrandVOS = kxsUserActTradeMapper.getUserActListByDayOrMonth(times, userId, 1, type, totalType);
        //判断是否二次查询
        if (lastMonthTimes != null) {
            List<TrendTimesVO> trendTimesActBrandVOSLast = kxsUserActTradeMapper.getUserActListByDayOrMonth(lastMonthTimes, userId, 1, type, totalType);
            trendTimesActBrandVOS.addAll(trendTimesActBrandVOSLast);
        }
        //构造数据
        ArrayList<TrendVO> trendVOSBrand = getTrendVOS(trendTimesActVOS, trendTimesActBrandVOS, times);
        statUserGetUserStatByDayOrMonthVO.setActMerchantTrend(trendVOSBrand);//激活趋势图
    }

    private void setActTotalAndPercent(Long userId, List<String> times, List<String> lastMonthTimes, StatUserGetUserStatByDayOrMonthVO statUserGetUserStatByDayOrMonthVO, Integer type, Integer totalType) {
        //获取传入日期激活商户数根据品牌分组
        List<PercentVO> percentVOSAct = kxsUserActTradeMapper.getUserTradeTotal(times, userId, type, totalType);
        //判断是否二次查询
        if (lastMonthTimes != null) {
            List<PercentVO> percentVOSActLast = kxsUserActTradeMapper.getUserTradeTotal(lastMonthTimes, userId, type, totalType);
            percentVOSAct.addAll(percentVOSActLast);
        }
        //总激活数
        Integer actTotalCount = 0;
        for (PercentVO percentVO : percentVOSAct) {
            actTotalCount += percentVO.getTotal();
        }
        //计算百分比
        for (PercentVO percentVO : percentVOSAct) {
            percentVO.setPercent(BigDecimal.valueOf(percentVO.getTotal()).divide(BigDecimal.valueOf(actTotalCount), 6, RoundingMode.HALF_UP));
        }
        statUserGetUserStatByDayOrMonthVO.setActMerchantPercent(percentVOSAct);//激活百分比
        statUserGetUserStatByDayOrMonthVO.setActMerchantTotal(actTotalCount);//激活总数
    }

    private void setTreadeTotalAndPercent(Long userId, List<String> times, List<String> lastMonthTimes, StatUserGetUserStatByDayOrMonthVO statUserGetUserStatByDayOrMonthVO, Integer type, Integer totalType) {
        String thisMoth = LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.SIMPLE_MONTH_PATTERN);
        String tableName = PREFIX_TABLE_NAME + thisMoth;
        //获取全部品牌总交易额
        List<PercentVO> percentVOS = baseMapper.getUserTradeTotal(tableName, userId, times, type, totalType);
        //判断是否二次查询
        if (lastMonthTimes != null) {
            //需要构造上月表名
            LocalDate date = LocalDate.now().minusMonths(1);//月份减一
            String lastMoth = LocalDateTimeUtil.format(date, DatePattern.SIMPLE_MONTH_PATTERN);
            String lastTableName = PREFIX_TABLE_NAME + lastMoth;
            List<PercentVO> percentVOSLast = baseMapper.getUserTradeTotal(lastTableName, userId, lastMonthTimes, type, totalType);
            percentVOS.addAll(percentVOSLast);
        }
        BigDecimal totalAmout = BigDecimal.ZERO;
        //计算总金额
        for (PercentVO percentVO : percentVOS) {
            totalAmout = totalAmout.add(percentVO.getAmount());
        }
        //计算百分比
        for (PercentVO percentVO : percentVOS) {
            percentVO.setPercent(percentVO.getAmount().divide(totalAmout, 6, RoundingMode.HALF_UP));
        }
        statUserGetUserStatByDayOrMonthVO.setTreadePercent(percentVOS);//交易百分比
        statUserGetUserStatByDayOrMonthVO.setTreadeTotal(totalAmout);//交易总额
    }

    private void setTreadeTrend(Long userId, LocalDate now, List<String> times, List<String> lastMonthTimes, StatUserGetUserStatByDayOrMonthVO statUserGetUserStatByDayOrMonthVO, Integer type, Integer totalType) {
        String thisMoth = LocalDateTimeUtil.format(now, DatePattern.SIMPLE_MONTH_PATTERN);
        String tableName = PREFIX_TABLE_NAME + thisMoth;
        List<TrendTimesVO> trendTimesVOS = new ArrayList<>();
        if (type == 1) {
            //查询用户全部交易额根据日期分组
            trendTimesVOS = baseMapper.getUserTradeListByDayOrMonth(tableName, times, userId, null, type, totalType);
            //判断是否需要二次查询
            if (lastMonthTimes != null) {
                //需要构造上月表名
                LocalDate date = now.minusMonths(1);//月份减一
                String lastMoth = LocalDateTimeUtil.format(date, DatePattern.SIMPLE_MONTH_PATTERN);
                String lastTableName = PREFIX_TABLE_NAME + lastMoth;
                try {
                    //因为这里可能存在查询的月份的表未创建的原因  使用try包裹跳过报错  视为该月无数据
                    List<TrendTimesVO> trendTimesVOSByLastMonthTimes = baseMapper.getUserTradeListByDayOrMonth(lastTableName, lastMonthTimes, userId, null, type, totalType);
                    trendTimesVOS.addAll(trendTimesVOSByLastMonthTimes);
                } catch (Exception e) {
                    log.info(e.getMessage());
                }
            }
        } else {
            for (String month : times) {
                //拼接表名
                String newTableName = PREFIX_TABLE_NAME + month;
                //因为这里可能存在查询的月份的表未创建的原因  使用try包裹跳过报错  视为该月无数据
                try {
                    List<TrendTimesVO> userTradeListByDayOrMonth = baseMapper.getUserTradeListByDayOrMonth(newTableName, times, userId, null, type, totalType);
                    trendTimesVOS.addAll(userTradeListByDayOrMonth);
                } catch (Exception e) {
                    log.info(e.getMessage());
                }
            }
        }
        //查询用户全部交易额根据 日期以及品牌 分组
        List<TrendTimesVO> trendTimesVOListBrand = baseMapper.getUserTradeListByDayOrMonth(tableName, times, userId, 1, type, totalType);
        //判断是否需要二次查询
        if (lastMonthTimes != null) {
            //需要构造上月表名
            LocalDate date = now.minusMonths(1);//月份减一
            String lastMoth = LocalDateTimeUtil.format(date, DatePattern.SIMPLE_MONTH_PATTERN);
            String lastTableName = PREFIX_TABLE_NAME + lastMoth;
            List<TrendTimesVO> trendTimesVOListBrandLast = baseMapper.getUserTradeListByDayOrMonth(lastTableName, lastMonthTimes, userId, 1, type, totalType);
            trendTimesVOListBrand.addAll(trendTimesVOListBrandLast);
        }
        //构造数据
        ArrayList<TrendVO> trendVOS = getTrendVOS(trendTimesVOS, trendTimesVOListBrand, times);
        statUserGetUserStatByDayOrMonthVO.setTreadeTrend(trendVOS);//交易趋势
    }

    private static void repZero(List<String> times, List<TrendTimesVO> trendTimesVOS) {
        for (String time : times) {
            //补充标识
            int repFlag = 0;
            Integer brandId = null;
            for (TrendTimesVO trendTimesVO : trendTimesVOS) {
                brandId = trendTimesVO.getBrandId();
                //如果存在则开启标识
                if (time.equals(trendTimesVO.getTime())) {
                    repFlag = 1;
                }
            }
            //当返回集合中不存在查询的时间则构造一条0数据加入trendTimesVOS集合
            if (repFlag == 0) {
                TrendTimesVO trendTimesVO = new TrendTimesVO();
                trendTimesVO.setTime(time);
                trendTimesVO.setTotal(0);
                trendTimesVO.setBrandId(brandId);
                trendTimesVOS.add(trendTimesVO);
            }
        }
    }

    private static ArrayList<TrendVO> getTrendVOS(List<TrendTimesVO> trendTimesVOS, List<TrendTimesVO> trendTimesVOListBrand, List<String> times) {
        //将全部交易额以及品牌交易额构造进入map  key为品牌id  或  all
        Map<String, List<TrendTimesVO>> treadTrend = new HashMap<>();
        treadTrend.put("all", trendTimesVOS);
        for (TrendTimesVO trendTimesVO : trendTimesVOListBrand) {
            List<TrendTimesVO> trendTimesVOSBrand = treadTrend.get(trendTimesVO.getBrandId() == null ? null : trendTimesVO.getBrandId().toString());
            if (trendTimesVOSBrand == null) {
                //未查询到则构造map  key为品牌id
                trendTimesVOSBrand = new ArrayList<>();
                trendTimesVOSBrand.add(trendTimesVO);
                treadTrend.put(trendTimesVO.getBrandId() != null ? trendTimesVO.getBrandId().toString() : "all", trendTimesVOSBrand);
            } else {
                trendTimesVOSBrand.add(trendTimesVO);
            }
        }
        //将map转换为返回实体类
        ArrayList<TrendVO> trendVOS = new ArrayList<>();
        for (Map.Entry<String, List<TrendTimesVO>> entry : treadTrend.entrySet()) {
            //补0数据
            repZero(times, entry.getValue());
            TrendVO trendVO = new TrendVO();
            trendVO.setName(entry.getKey());
            trendVO.setTimes(entry.getValue());
            trendVOS.add(trendVO);
        }
        return trendVOS;
    }


}

