package com.jsowell.pile.service.impl;

import com.alibaba.fastjson2.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jsowell.adapay.dto.QueryPaymentConfirmDTO;
import com.jsowell.adapay.response.QueryPaymentConfirmDetailResponse;
import com.jsowell.adapay.service.AdapayService;
import com.jsowell.common.constant.Constants;
import com.jsowell.common.core.page.PageResponse;
import com.jsowell.common.enums.DelFlagEnum;
import com.jsowell.common.exception.BusinessException;
import com.jsowell.common.util.DateUtils;
import com.jsowell.common.util.PageUtils;
import com.jsowell.common.util.StringUtils;
import com.jsowell.common.util.id.IdUtils;
import com.jsowell.pile.domain.PileStationInfo;
import com.jsowell.pile.domain.SettleOrderReport;
import com.jsowell.pile.dto.GetClearingBillDTO;
import com.jsowell.pile.dto.MerchantOrderReportDTO;
import com.jsowell.pile.dto.QueryOrderDTO;
import com.jsowell.pile.dto.SettleOrderReportDTO;
import com.jsowell.pile.mapper.AdapayCallbackRecordMapper;
import com.jsowell.pile.mapper.OrderBasicInfoMapper;
import com.jsowell.pile.mapper.SettleOrderReportMapper;
import com.jsowell.pile.service.*;
import com.jsowell.pile.vo.base.SplitSettleAmountVO;
import com.jsowell.pile.vo.web.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 结算订单报Service业务层处理
 *
 * @author jsowell
 * @date 2023-06-05
 */
@Slf4j
@Service
public class SettleOrderReportServiceImpl implements ISettleOrderReportService {
    @Autowired
    private SettleOrderReportMapper settleOrderReportMapper;

    @Autowired
    private OrderBasicInfoMapper orderBasicInfoMapper;

    @Autowired
    private IPileStationInfoService pileStationInfoService;

    @Autowired
    private AdapayCallbackRecordMapper adapayCallbackRecordMapper;

    @Autowired
    private AdapayService adapayService;

    @Autowired
    private IPileMerchantInfoService pileMerchantInfoService;

    @Autowired
    private ClearingWithdrawInfoService clearingWithdrawInfoService;

    @Autowired
    private ClearingBillInfoService clearingBillInfoService;


    /**
     * 查询结算订单报
     *
     * @param id 结算订单报主键
     * @return 结算订单报
     */
    @Override
    public SettleOrderReport selectSettleOrderReportById(Long id) {
        return settleOrderReportMapper.selectSettleOrderReportById(id);
    }

    @Override
    public SettleOrderReport selectByStationIdAndDate(String stationId, String date) {
        return settleOrderReportMapper.selectByStationIdAndDate(stationId, date);
    }



    /**
     * 查询站点订单日报明细
     * 分页查询
     *
     * @param dto
     * @return
     */
    @Override
    public PageResponse selectSettleOrderReportDetail(SettleOrderReportDTO dto) {
        List<String> orderCodes = getOrderCodes(dto);

        // 查询订单支付信息 分页
        int pageNum = dto.getPageNum() != null ? dto.getPageNum() : 1;
        int pageSize = dto.getPageSize() != null ? dto.getPageSize() : 10;
        PageHelper.startPage(pageNum, pageSize);
        List<ClearingBillVO> clearingBillVOList = clearingWithdrawInfoService.selectWithdrawInfoByOrderCodeList(orderCodes);
        PageInfo<ClearingBillVO> pageInfo = new PageInfo<>(clearingBillVOList);

        // 封装结果集
        List<OrderSettleDetailVO> resultList = Lists.newArrayList();
        OrderSettleDetailVO vo = null;
        String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId());
        for (ClearingBillVO clearingBillVO : pageInfo.getList()) {
            vo = new OrderSettleDetailVO();
            vo.setOrderCode(clearingBillVO.getOrderCode());
            vo.setSettleAmount(clearingBillVO.getSettleAmount());
            String paymentId = clearingBillVO.getPaymentId();
            QueryPaymentConfirmDTO build = QueryPaymentConfirmDTO.builder()
                    .wechatAppId(wechatAppId)
                    .paymentId(paymentId)
                    .build();
            QueryPaymentConfirmDetailResponse response = adapayService.queryPaymentConfirmList(build);
            List<QueryPaymentConfirmDetailResponse.PaymentConfirmInfo> paymentConfirms = response.getPaymentConfirms();
            // 如果没有分账信息，说明没有清分
            String clearingStatus = null;
            if (CollectionUtils.isEmpty(paymentConfirms)) {
                clearingStatus = "未清分";
            } else {
                clearingStatus = "已清分";
            }
            vo.setClearingStatus(clearingStatus);
            if ("已清分".equals(vo.getClearingStatus())) {
                vo.setClearingBillCode(clearingBillVO.getClearingBillCode());
                vo.setWithdrawCode(clearingBillVO.getWithdrawCode());
                String withdrawStatus = null;
                if (StringUtils.equals(clearingBillVO.getWithdrawStatus(), "0")) {
                    withdrawStatus = "处理中";
                } else if (StringUtils.equals(clearingBillVO.getWithdrawStatus(), "1")){
                    withdrawStatus = "已提现";
                }
                vo.setWithdrawStatus(withdrawStatus);
            }
            resultList.add(vo);
        }
        PageResponse pageResponse = new PageResponse();
        pageResponse.setPageSize(pageInfo.getPageSize());
        pageResponse.setPageNum(pageInfo.getPageNum());
        pageResponse.setPages(pageInfo.getPages());
        pageResponse.setTotal(pageInfo.getTotal());
        pageResponse.setList(resultList);
        return pageResponse;
    }

    /**
     * 根据 merchantId 或 stationId 以及交易日期获取订单号
     * @param dto
     * @return
     */
    private List<String> getOrderCodes(SettleOrderReportDTO dto) {
        List<String> orderCodeList = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getMerchantId())) {
            List<PileStationInfo> stationIdInfos = pileStationInfoService.selectStationListByMerchantId(Long.parseLong(dto.getMerchantId()));
            // 收集出站点id
            List<String> stationIds = stationIdInfos.stream()
                    .map(PileStationInfo::getId)
                    .collect(Collectors.toList())
                    .stream()
                    .map(String::valueOf)
                    .collect(Collectors.toList());
            List<SettleOrderReport> list = queryOrderReport(stationIds, dto.getTradeDate(), dto.getTradeDate());
            if (CollectionUtils.isEmpty(list)) {
                return new ArrayList<>();
            }
            List<String> orderCodes = list.stream().map(SettleOrderReport::getOrderCodes)
                    .filter(StringUtils::isNotBlank)
                    .collect(Collectors.toList());
            if (CollectionUtils.isEmpty(orderCodes)) {
                return new ArrayList<>();
            }
            for (String orderCode : orderCodes) {
                orderCodeList = Lists.newArrayList(StringUtils.split(orderCode, ","));
            }
        } else if (StringUtils.isNotBlank(dto.getStationId())){
            SettleOrderReport orderReport = selectByStationIdAndDate(dto.getStationId(), dto.getTradeDate());

            if (orderReport == null) {
                return new ArrayList<>();
            }
            String orderCodes = orderReport.getOrderCodes();
            if (StringUtils.isBlank(orderCodes)) {
                return new ArrayList<>();
            }
            orderCodeList = Lists.newArrayList(StringUtils.split(orderCodes, ","));
            dto.setMerchantId(orderReport.getMerchantId());
        }
        return orderCodeList;
    }

    @Override
    public List<SettleOrderReport> selectByMerchantIdAndDate(String merchantId, String date) {
        return settleOrderReportMapper.selectByMerchantIdAndDate(merchantId, date);
    }

    /**
     * 查询结算订单报列表
     *
     * @param settleOrderReport 结算订单报
     * @return 结算订单报
     */
    @Override
    public List<SettleOrderReport> selectSettleOrderReportList(SettleOrderReport settleOrderReport) {
        return settleOrderReportMapper.selectSettleOrderReportList(settleOrderReport);
    }

    /**
     * 新增结算订单报
     *
     * @param settleOrderReport 结算订单报
     * @return 结果
     */
    @Override
    public int insertSettleOrderReport(SettleOrderReport settleOrderReport) {
        settleOrderReport.setCreateTime(DateUtils.getNowDate());
        return settleOrderReportMapper.insertSettleOrderReport(settleOrderReport);
    }

    /**
     * 修改结算订单报
     *
     * @param settleOrderReport 结算订单报
     * @return 结果
     */
    @Override
    public int updateSettleOrderReport(SettleOrderReport settleOrderReport) {
        return settleOrderReportMapper.updateSettleOrderReport(settleOrderReport);
    }

    /**
     * 批量删除结算订单报
     *
     * @param ids 需要删除的结算订单报主键
     * @return 结果
     */
    @Override
    public int deleteSettleOrderReportByIds(Long[] ids) {
        return settleOrderReportMapper.deleteSettleOrderReportByIds(ids);
    }

    /**
     * 删除结算订单报信息
     *
     * @param id 结算订单报主键
     * @return 结果
     */
    @Override
    public int deleteSettleOrderReportById(Long id) {
        return settleOrderReportMapper.deleteSettleOrderReportById(id);
    }

    /**
     * 根据运营商id查询订单报表
     *
     * @param dto
     * @return
     */
    @Override
    public MerchantOrderReportVO getMerchantOrderReport(MerchantOrderReportDTO dto) {
        int pageNum = dto.getPageNum() == null ? 1 : dto.getPageNum();
        int pageSize = dto.getPageSize() == null ? 10 : dto.getPageSize();
        if (StringUtils.isBlank(dto.getStartTime())) {
            dto.setStartTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.addDays(new Date(), -7)));
        }
        if (StringUtils.isBlank(dto.getEndTime())) {
            dto.setEndTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, new Date()));
        }
        MerchantOrderReportVO vo = new MerchantOrderReportVO();
        MerchantOrderReportVO.MerchantOrderReport report = new MerchantOrderReportVO.MerchantOrderReport();
        PageUtils.startPage(pageNum, pageSize);
        List<SettleOrderReportVO> pageList = settleOrderReportMapper.getMerchantOrderReport(dto);
        if (CollectionUtils.isEmpty(pageList)) {
            return null;
        }
        List<SettleOrderReportVO> list = settleOrderReportMapper.getMerchantOrderReport(dto);
        PageInfo<SettleOrderReportVO> pageInfo = new PageInfo<>(pageList);
        vo.setMerchantId(dto.getMerchantId());
        // vo.setReportList(pageInfo.getList());

        PageResponse pageResponse = PageResponse.builder()
                .pageSize(pageSize)
                .pageNum(pageNum)
                .pages(pageInfo.getPages())
                .total(pageInfo.getTotal())
                .list(pageInfo.getList())

                .build();
        vo.setPageResponse(pageResponse);
        // 进行数据汇总
        // 用电度数
        report.setUseElectricity(list.stream().map(SettleOrderReportVO::getUseElectricity).reduce(BigDecimal.ZERO, BigDecimal::add));
        // 充电次数
        report.setChargeNum(list.stream().map(SettleOrderReport -> new BigDecimal(SettleOrderReport.getChargeNum())).reduce(BigDecimal.ZERO, BigDecimal::add));
        // 充电时长
        report.setChargeTime(list.stream().map(SettleOrderReport -> new BigDecimal(SettleOrderReport.getChargeTime())).reduce(BigDecimal.ZERO, BigDecimal::add));
        // 电费金额
        report.setElectricityAmount(list.stream().map(SettleOrderReportVO::getElectricityAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
        // 服务费金额
        report.setServiceAmount(list.stream().map(SettleOrderReportVO::getServiceAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
        // 收入金额
        report.setTotalAmount(list.stream().map(SettleOrderReportVO::getTotalAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
        // 虚拟金额
        report.setVirtualAmount(list.stream().map(SettleOrderReportVO::getVirtualAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
        // 交易金额
        report.setTradeAmount(list.stream().map(SettleOrderReportVO::getTradeAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
        // 交易手续费
        report.setTradeFee(list.stream().map(SettleOrderReportVO::getTradeFee).reduce(BigDecimal.ZERO, BigDecimal::add));

        vo.setMerchantOrderReport(report);
        return vo;
    }

    /**
     * 根据运营商id查询订单报表V2
     *
     * @param dto
     * @return
     */
    @Override
    public MerchantOrderReportVO getMerchantOrderReportV2(MerchantOrderReportDTO dto) {
        int pageNum = dto.getPageNum() == null ? 1 : dto.getPageNum();
        int pageSize = dto.getPageSize() == null ? 10 : dto.getPageSize();
        if (StringUtils.isBlank(dto.getStartTime())) {
            dto.setStartTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.addDays(new Date(), -7)));
        }
        if (StringUtils.isBlank(dto.getEndTime())) {
            dto.setEndTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, new Date()));
        }
        MerchantOrderReportVO vo = new MerchantOrderReportVO();
        vo.setMerchantId(dto.getMerchantId());
        PageUtils.startPage(pageNum, pageSize);
        GetClearingBillDTO clearingBillDTO = GetClearingBillDTO.builder()
                .merchantId(dto.getMerchantId())
                .startTime(dto.getStartTime())
                .endTime(dto.getEndTime())
                .pageNum(dto.getPageNum())
                .pageSize(dto.getPageSize())
                .build();
        // 清分账单列表
        PageResponse pageResponse = getMerchantClearingBillList(clearingBillDTO);
        vo.setPageResponse(pageResponse);

        // 进行数据汇总
        MerchantOrderReportVO.MerchantOrderReport report = queryMerchantOrderReport(dto);
        vo.setMerchantOrderReport(report);
        return vo;
    }

    private MerchantOrderReportVO.MerchantOrderReport queryMerchantOrderReport(MerchantOrderReportDTO dto) {
        // 进行数据汇总
        MerchantOrderReportVO.MerchantOrderReport report = new MerchantOrderReportVO.MerchantOrderReport();
        List<SettleOrderReportVO> list = settleOrderReportMapper.getMerchantOrderReport(dto);
        BigDecimal useElectricity = BigDecimal.ZERO;
        BigDecimal chargeNum = BigDecimal.ZERO;
        BigDecimal chargeTime = BigDecimal.ZERO;
        BigDecimal electricityAmount = BigDecimal.ZERO;
        BigDecimal serviceAmount = BigDecimal.ZERO;
        BigDecimal totalAmount = BigDecimal.ZERO;
        BigDecimal virtualAmount = BigDecimal.ZERO;
        for (SettleOrderReportVO settleOrderReportVO : list) {
            useElectricity = useElectricity.add(settleOrderReportVO.getUseElectricity());
            chargeNum = chargeNum.add(new BigDecimal(settleOrderReportVO.getChargeNum()));
            chargeTime = chargeTime.add(new BigDecimal(settleOrderReportVO.getChargeTime()));
            electricityAmount = electricityAmount.add(settleOrderReportVO.getElectricityAmount());
            serviceAmount = serviceAmount.add(settleOrderReportVO.getServiceAmount());
            totalAmount = totalAmount.add(settleOrderReportVO.getTotalAmount());
            virtualAmount = virtualAmount.add(settleOrderReportVO.getVirtualAmount());
        }
        // 用电度数
        report.setUseElectricity(useElectricity);
        // 充电次数
        report.setChargeNum(chargeNum);
        // 充电时长
        report.setChargeTime(chargeTime);
        // 电费金额
        report.setElectricityAmount(electricityAmount);
        // 服务费金额
        report.setServiceAmount(serviceAmount);
        // 收入金额
        report.setTotalAmount(totalAmount);
        // 虚拟金额
        report.setVirtualAmount(virtualAmount);
        // 交易金额
        // report.setTradeAmount(list.stream().map(SettleOrderReportVO::getTradeAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
        // 交易手续费
        // report.setTradeFee(list.stream().map(SettleOrderReportVO::getTradeFee).reduce(BigDecimal.ZERO, BigDecimal::add));

        // 从清分账单中计算交易金额，交易手续费
        GetClearingBillDTO clearingBillDTO = GetClearingBillDTO.builder()
                .merchantId(dto.getMerchantId())
                .startTime(dto.getStartTime())
                .endTime(dto.getEndTime())
                .build();
        PageHelper.clearPage();
        List<MerchantClearingBillVO> merchantClearingBillList = clearingBillInfoService.getMerchantClearingBillList(clearingBillDTO);
        BigDecimal tradeAmount = BigDecimal.ZERO;
        BigDecimal tradeFee = BigDecimal.ZERO;
        for (MerchantClearingBillVO merchantClearingBillVO : merchantClearingBillList) {
            tradeAmount = tradeAmount.add(new BigDecimal(merchantClearingBillVO.getWithdrawAbleAmount()));
            tradeFee = tradeFee.add(new BigDecimal(merchantClearingBillVO.getFeeAmount()));
        }
        // 交易金额
        report.setTradeAmount(tradeAmount);
        // 交易手续费
        report.setTradeFee(tradeFee);
        return report;
    }

    /**
     * 获取运营商清分账单列表
     * @param dto
     * @return
     */
    @Override
    public PageResponse getMerchantClearingBillList(GetClearingBillDTO dto) {
        int pageNum = dto.getPageNum() == null ? 1 : dto.getPageNum();
        int pageSize = dto.getPageSize() == null ? 10 : dto.getPageSize();
        // 分页
        PageUtils.startPage(pageNum, pageSize);
        List<MerchantClearingBillVO> resultList = clearingBillInfoService.getMerchantClearingBillList(dto);
        if (CollectionUtils.isEmpty(resultList)) {
            return null;
        }
        PageInfo<MerchantClearingBillVO> pageInfo = new PageInfo<>(resultList);
        PageResponse response = PageResponse.builder()
                .pageNum(pageInfo.getPageNum())
                .pageSize(pageInfo.getPageSize())
                .list(pageInfo.getList())
                .total(pageInfo.getTotal())
                .pages(pageInfo.getPages())
                .build();
        return response;
    }

    @Override
    public int deleteByPrimaryKey(Integer id) {
        return settleOrderReportMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int insert(SettleOrderReport record) {
        return settleOrderReportMapper.insert(record);
    }

    @Override
    public int insertOrUpdate(SettleOrderReport record) {
        Date nowDate = DateUtils.getNowDate();
        if (record.getId() == null) {
            record.setCreateTime(nowDate);
        } else {
            record.setUpdateTime(nowDate);
        }
        return settleOrderReportMapper.insertOrUpdate(record);
    }

    @Override
    public int insertOrUpdateSelective(SettleOrderReport record) {
        return settleOrderReportMapper.insertOrUpdateSelective(record);
    }

    @Override
    public int insertSelective(SettleOrderReport record) {
        return settleOrderReportMapper.insertSelective(record);
    }

    @Override
    public SettleOrderReport selectByPrimaryKey(Integer id) {
        return settleOrderReportMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateByPrimaryKeySelective(SettleOrderReport record) {
        return settleOrderReportMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(SettleOrderReport record) {
        return settleOrderReportMapper.updateByPrimaryKey(record);
    }

    @Override
    public int updateBatch(List<SettleOrderReport> list) {
        return settleOrderReportMapper.updateBatch(list);
    }

    @Override
    public int updateBatchSelective(List<SettleOrderReport> list) {
        return settleOrderReportMapper.updateBatchSelective(list);
    }

    @Override
    public int batchInsert(List<SettleOrderReport> list) {
        return settleOrderReportMapper.batchInsert(list);
    }

    @Override
    public List<SettleOrderReport> queryOrderReport(List<String> stationIdList, String startTime, String endTime) {
        return settleOrderReportMapper.queryOrderReport(stationIdList, startTime, endTime);
    }

    @Override
    public Map<String, Object> queryUndividedOrder(SettleOrderReportDTO dto) {
        Map<String, Object> resultMap = Maps.newHashMap();

        SettleOrderReport orderReport = selectByStationIdAndDate(dto.getStationId(), dto.getTradeDate());
        if (orderReport == null) {
            throw new BusinessException("00300002", "查询站点订单日报为空");
        }
        String orderCodes = orderReport.getOrderCodes();
        List<String> orderCodeList = Lists.newArrayList(StringUtils.split(orderCodes, ","));
        List<ClearingBillVO> clearingBillVOList = clearingWithdrawInfoService.selectWithdrawInfoByOrderCodeList(orderCodeList);
        if (CollectionUtils.isEmpty(clearingBillVOList)) {
            throw new BusinessException("00300005", "查询清分信息为空");
        }
        String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(orderReport.getMerchantId());
        // clearing
        List<ClearingBillVO> clearingList = Lists.newArrayList();
        List<ClearingBillVO> unClearingList = Lists.newArrayList();
        for (ClearingBillVO clearingBillVO : clearingBillVOList) {
            String paymentId = clearingBillVO.getPaymentId();
            QueryPaymentConfirmDTO build = QueryPaymentConfirmDTO.builder()
                    .wechatAppId(wechatAppId)
                    .paymentId(paymentId)
                    .build();
            QueryPaymentConfirmDetailResponse response = adapayService.queryPaymentConfirmList(build);
            List<QueryPaymentConfirmDetailResponse.PaymentConfirmInfo> paymentConfirms = response.getPaymentConfirms();
            if (!CollectionUtils.isEmpty(paymentConfirms)) {
                clearingBillVO.setConfirmInfo(paymentConfirms.get(0));
                clearingList.add(clearingBillVO);
            } else {
                unClearingList.add(clearingBillVO);
            }
        }
        resultMap.put("clearingList", clearingList);
        resultMap.put("unClearingList", unClearingList);
        return resultMap;
    }

    /**
     * 计算站点订单报表
     *
     * @param stationId 站点id
     * @param tradeDate 交易日期
     */
    @Override
    public void generateDailyOrderReports(String stationId, String tradeDate) {
        // logger.info("线程名===={}", Thread.currentThread().getName());
        if (StringUtils.isBlank(stationId)) {
            return;
        }
        if (StringUtils.isBlank(tradeDate)) {
            // 日期为空默认昨天
            tradeDate = LocalDate.now().plusDays(-1).toString();
        }
        PileStationVO stationInfo = pileStationInfoService.getStationInfo(stationId);
        // 查询站点前一天结算完成的订单
        QueryOrderDTO dto = new QueryOrderDTO();
        dto.setStationId(stationId);
        LocalDate parse = LocalDate.parse(tradeDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String startTime = DateUtils.formatDateTime(LocalDateTime.of(parse, LocalTime.MIN));
        String endTime = DateUtils.formatDateTime(LocalDateTime.of(parse, LocalTime.MAX));
        dto.setStartSettleTime(startTime);
        dto.setEndSettleTime(endTime);
        // 查询结算完成的订单
        List<OrderListVO> orderListVOS = orderBasicInfoMapper.selectOrderBasicInfoList(dto);
        // if (CollectionUtils.isEmpty(orderListVOS)) {
        //     logger.info("站点:{}, 在{}-{}没有查询到订单数据", stationInfo.getStationName(), startTime, endTime);
        //     return;
        // }
        List<String> collect = orderListVOS.stream().map(OrderListVO::getOrderCode).collect(Collectors.toList());
        log.info("站点:{}, 在{}-{}查询到订单数据{}条，订单编号:{}", stationInfo.getStationName(), startTime, endTime, orderListVOS.size(), collect);
        // 统计出日报信息
        BigDecimal useElectricity = BigDecimal.ZERO;
        int chargeNum = 0;
        long chargeTime = 0L;
        BigDecimal totalElectricityAmount = BigDecimal.ZERO;
        BigDecimal totalServiceAmount = BigDecimal.ZERO;
        BigDecimal totalOrderAmount = BigDecimal.ZERO;
        BigDecimal totalVirtualAmount = BigDecimal.ZERO;
        BigDecimal totalSettleAmount = BigDecimal.ZERO;
        // 总手续费
        BigDecimal totalFeeAmount = BigDecimal.ZERO;
        BigDecimal totalTradeAmount = BigDecimal.ZERO;

        List<String> orderCodeList = Lists.newArrayList();
        for (OrderListVO vo : orderListVOS) {
            // 统计结算金额大于0的
            BigDecimal settleAmount = StringUtils.isBlank(vo.getSettleAmount())
                    ? BigDecimal.ZERO
                    : new BigDecimal(vo.getSettleAmount());
            if (settleAmount.compareTo(BigDecimal.ZERO) <= 0) {
                // 只统计用电量大于0的
                continue;
            }

            // 订单消费金额
            String orderAmount = vo.getOrderAmount();

            // 用电度数
            BigDecimal chargingDegree = StringUtils.isBlank(vo.getChargingDegree())
                    ? BigDecimal.ZERO
                    : new BigDecimal(vo.getChargingDegree());

            // 充电度数累计
            useElectricity = useElectricity.add(chargingDegree);

            // 充电次数
            chargeNum += 1;
            orderCodeList.add(vo.getOrderCode());

            // 充电时间累计
            if (StringUtils.isNotBlank(vo.getChargeStartTime()) && StringUtils.isNotBlank(vo.getChargeEndTime())) {
                long l = DateUtils.intervalTime(vo.getChargeStartTime(), vo.getChargeEndTime());
                chargeTime += l;
            }

            // 电费金额
            BigDecimal e = vo.getTotalElectricityAmount() != null ? vo.getTotalElectricityAmount() : BigDecimal.ZERO;
            totalElectricityAmount = totalElectricityAmount.add(e);

            // 服务费金额
            BigDecimal serviceAmount = vo.getTotalServiceAmount() != null ? vo.getTotalServiceAmount() : BigDecimal.ZERO;
            totalServiceAmount = totalServiceAmount.add(serviceAmount);

            // 订单金额
            totalOrderAmount = totalOrderAmount.add(new BigDecimal(orderAmount));

            // 虚拟金额
            String virtualAmount = StringUtils.isNotBlank(vo.getVirtualAmount()) ? vo.getVirtualAmount() : Constants.ZERO;
            totalVirtualAmount = totalVirtualAmount.add(new BigDecimal(virtualAmount));

            // 结算金额
            totalSettleAmount = totalSettleAmount.add(settleAmount);

            // 计算手续费 = 结算金额 * 0.55%
            SplitSettleAmountVO splitSettleAmountVO = splitSettleAmount(settleAmount);
            totalFeeAmount = totalFeeAmount.add(splitSettleAmountVO.getFeeAmount());
            totalTradeAmount = totalTradeAmount.add(splitSettleAmountVO.getTradeAmount());
        }

        // 计算报表
        SettleOrderReport settleOrderReport = new SettleOrderReport();
        String settleCode = "SETTLE_" + IdUtils.getOrderCode();
        settleOrderReport.setSettleCode(settleCode);
        settleOrderReport.setMerchantId(stationInfo.getMerchantId());
        settleOrderReport.setStationId(stationId);
        settleOrderReport.setUseElectricity(useElectricity);
        settleOrderReport.setChargeNum(chargeNum + "");
        settleOrderReport.setChargeTime(chargeTime + "");
        settleOrderReport.setElectricityAmount(totalElectricityAmount);
        settleOrderReport.setServiceAmount(totalServiceAmount);
        settleOrderReport.setTotalAmount(totalOrderAmount);
        settleOrderReport.setVirtualAmount(totalVirtualAmount);
        settleOrderReport.setTradeDate(tradeDate);
        settleOrderReport.setOrderCodes(Joiner.on(",").join(orderCodeList));
        // 计算手续费 = 结算金额 * 0.55%
        // SplitSettleAmountVO splitSettleAmountVO = splitSettleAmount(totalSettleAmount);
        settleOrderReport.setTradeFee(totalFeeAmount);
        settleOrderReport.setTradeAmount(totalTradeAmount);
        // 根据站点id和交易日期查询
        SettleOrderReport selectResult = this.selectByStationIdAndDate(stationId, tradeDate);
        if (selectResult != null) {
            settleOrderReport.setId(selectResult.getId());
        }
        settleOrderReport.setDelFlag(DelFlagEnum.NORMAL.getValue());
        // 订单日报 新增或更新
        this.insertOrUpdate(settleOrderReport);
    }

    /**
     * 通过结算金额，计算客户到账金额和手续费
     *
     * @param settleAmount 需要拆分的结算金额
     * @return
     */
    private SplitSettleAmountVO splitSettleAmount(BigDecimal settleAmount) {
        SplitSettleAmountVO resultVO = new SplitSettleAmountVO();
        if (settleAmount == null) {
            return resultVO;
        }
        // 计算手续费 = 结算金额 * 0.55%
        BigDecimal fee = settleAmount.multiply(new BigDecimal(Constants.FEE_RATES)).setScale(2, RoundingMode.UP);
        resultVO.setSettleAmount(settleAmount);
        resultVO.setFeeAmount(fee);
        resultVO.setTradeAmount(settleAmount.subtract(fee));
        return resultVO;
    }

    public static void main(String[] args) {
        List<String> list = Lists.newArrayList(
                "17.56",
                "26.13",
                "11.79",
                "34.80",
                "12.72",
                "18.03",
                "19.80",
                "66.76",
                "15.27",
                "37.50",
                "28.45",
                "24.81",
                "16.75");

        // 总手续费
        BigDecimal totalFeeAmount = BigDecimal.ZERO;
        BigDecimal totalTradeAmount = BigDecimal.ZERO;

        for (String s : list) {
            BigDecimal settleAmount = new BigDecimal(s);
            BigDecimal feeAmount = settleAmount.multiply(new BigDecimal(Constants.FEE_RATES)).setScale(2, RoundingMode.UP);
            // 交易金额 = 结算金额 - 手续费
            BigDecimal tradeAmount = settleAmount.subtract(feeAmount);

            totalFeeAmount = totalFeeAmount.add(feeAmount);
            totalTradeAmount = totalTradeAmount.add(tradeAmount);
        }

        System.out.println("总手续费" + totalFeeAmount);
        System.out.println("总交易金额" + totalTradeAmount);


        BigDecimal settleAmount = new BigDecimal("330.37");
        // 计算手续费 = 结算金额 * 0.55%
        BigDecimal fee = settleAmount.multiply(new BigDecimal(Constants.FEE_RATES));
        SplitSettleAmountVO resultVO = new SplitSettleAmountVO();
        resultVO.setSettleAmount(settleAmount);
        resultVO.setFeeAmount(fee);
        resultVO.setTradeAmount(settleAmount.subtract(fee));
        System.out.println(JSON.toJSONString(resultVO));
    }

}

