package com.xhpc.order.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.xhpc.common.api.SmsService;
import com.xhpc.common.core.utils.SecurityUtils;
import com.xhpc.common.core.web.domain.AjaxResult;
import com.xhpc.common.data.redis.CacheRealtimeData;
import com.xhpc.common.redis.service.RedisService;
import com.xhpc.order.domain.XhpcChargeOrder;
import com.xhpc.order.domain.XhpcHistoryOrder;
import com.xhpc.order.dto.XhpcChargeHistoryOrder;
import com.xhpc.order.mapper.XhpcHistoryOrderMapper;
import com.xhpc.order.service.IXhpcChargeOrderService;
import com.xhpc.order.service.IXhpcHistoryOrderService;
import com.xhpc.order.service.IXhpcRealTimeOrderService;
import org.apache.poi.util.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author yuyang
 * @date 2021/8/3 21:23
 */
@Service
public class XhpcHistoryOrderServiceImpl implements IXhpcHistoryOrderService {

    @Resource
    private XhpcHistoryOrderMapper xhpcHistoryOrderMapper;

    @Autowired
    private IXhpcChargeOrderService xhpcChargeOrderService;

    @Autowired
    private SmsService smsService;

    private final ExecutorService executorService = Executors.newFixedThreadPool(20);

    private static final Logger logger = LoggerFactory.getLogger(XhpcHistoryOrderServiceImpl.class);

    @Autowired
    private RedisService redisService;

    @Autowired
    private IXhpcRealTimeOrderService xhpcRealTimeOrderService;


    @Override
    public List<Map<String, Object>> list(Long userId) {

        return xhpcHistoryOrderMapper.list(userId);
    }

    @Override
    public int update(XhpcHistoryOrder xhpcHistoryOrder) {

        return xhpcHistoryOrderMapper.update(xhpcHistoryOrder);
    }

    @Override
    public AjaxResult gethistotyOrderMessage(Long userId, Long historyOrderId, Integer type, Long chargingOrderId) {

        return AjaxResult.success(xhpcHistoryOrderMapper.gethistotyOrderMessage(userId, historyOrderId, type, chargingOrderId));
    }

    @Override
    public void insert(XhpcHistoryOrder xhpcHistoryOrder) {

        xhpcHistoryOrderMapper.insert(xhpcHistoryOrder);
    }

    @Override
    public List<Map<String, Object>> getListPage(String phone, String transactionNumber, Integer status, String chargingStationName, Long operatorId, Integer source, String beginStartTime, String beginEndTime, Long userId, Integer type,String affiliationOrganization,String evcsOrderNo,String plateNum,Integer internetId,String internetSerialNumber,String terminalName,String vinCode,String overStartTime,String overEndTime) {

        Integer number = 0;
        if (!"".equals(phone) && phone != null && !"".equals(source) && source != null) {
            number = 3;
        } else if (!"".equals(phone) && phone != null) {
            number = 1;
        } else {
            number = 2;
        }
        //获取登陆用户
        Long logUserId = SecurityUtils.getUserId();
        //桩的统计、该时段金额
        List<Map<String, Object>> list = new ArrayList<>();
        if (userId != 1) {
            Map<String, Object> landUser = xhpcHistoryOrderMapper.getLandUser(logUserId);
            if (landUser != null) {
                if (landUser.get("userType") != null) {
                    if ("01".equals(landUser.get("userType").toString()) || "03".equals(landUser.get("userType").toString())) {
                        Long logOperatorId = Long.valueOf(landUser.get("operatorId").toString());
                        //运营商看自己的场站
                        list = xhpcHistoryOrderMapper.getListPage(phone, transactionNumber, 1, chargingStationName, operatorId, source, beginStartTime, beginEndTime, logOperatorId, type, number,affiliationOrganization,evcsOrderNo,plateNum,internetId,internetSerialNumber,terminalName,vinCode,overStartTime,overEndTime);
                    } else {
                        //查询赋值的场站
                        list = xhpcHistoryOrderMapper.getListPage(phone, transactionNumber, 2, chargingStationName, operatorId, source, beginStartTime, beginEndTime, logUserId, type, number,affiliationOrganization,evcsOrderNo,plateNum,internetId,internetSerialNumber,terminalName,vinCode,overStartTime,overEndTime);
                    }
                }
            }

        } else {
            list = xhpcHistoryOrderMapper.getListPage(phone, transactionNumber, 0, chargingStationName, operatorId, source, beginStartTime, beginEndTime, userId, type, number,affiliationOrganization,evcsOrderNo,plateNum,internetId,internetSerialNumber,terminalName,vinCode,overStartTime,overEndTime);
        }
        return list;
    }


    @Override
    public void export(HttpServletResponse response, String phone, String transactionNumber, Integer status, String chargingStationName, Long operatorId, Integer source, String beginStartTime, String beginEndTime, Long userId, Integer type,String affiliationOrganization,String evcsOrderNo,String plateNum,Integer internetId,String internetSerialNumber,String terminalName,String vinCode,String overStartTime,String overEndTime) throws IOException {

        List<Map<String, Object>> list = getListPage(phone, transactionNumber, status, chargingStationName, operatorId, source, beginStartTime, beginEndTime, userId, type,affiliationOrganization,evcsOrderNo,plateNum,internetId,internetSerialNumber,terminalName,vinCode,overStartTime,overEndTime);
        // 通过工具类创建writer，默认创建xls格式
        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.addHeaderAlias("historyOrderId", "历史订单ID");
        writer.addHeaderAlias("serialNumber", "订单号");
        writer.addHeaderAlias("chargingStationName", "电站名称");
        writer.addHeaderAlias("pileSerialNumber", "桩编号");
        writer.addHeaderAlias("terminalName", "终端名称");
        writer.addHeaderAlias("operatorId", "运营商ID");
        writer.addHeaderAlias("operatorName", "运营商名称");
        writer.addHeaderAlias("power", "功率");
        writer.addHeaderAlias("type", "桩类型(1直流（慢） 2交流（快）");
        writer.addHeaderAlias("orderType", "状态1 自动结算 2 平台结算");
        writer.addHeaderAlias("startSoc", "开始soc");
        writer.addHeaderAlias("endSoc", "结束soc");
//        writer.addHeaderAlias("internetSerialNumber", "电站名称");
        writer.addHeaderAlias("totalPrice", "订单总价");
        writer.addHeaderAlias("actPrice", "实际价格");
//        writer.addHeaderAlias("confirmResult", "历史订单ID");
        writer.addHeaderAlias("chargingTime", "累计充电时间");
        writer.addHeaderAlias("chargingDegree", "充电度数");
        writer.addHeaderAlias("startTime", "开始充电时间");
        writer.addHeaderAlias("endTime", "结束充电时间");
        writer.addHeaderAlias("updateTime", "结算时间");
        writer.addHeaderAlias("source", "订单来源（0C端用户 1流量用户）");
//        writer.addHeaderAlias("plateNum", "电站名称");
//        writer.addHeaderAlias("disputeOrderStatus", "桩编号");

        // 默认的，未添加alias的属性也会写出，如果想只写出加了别名的字段，可以调用此方法排除之
        writer.setOnlyAlias(true);
        // 一次性写出内容，使用默认样式，强制输出标题
        writer.write(list, true);
        //out为OutputStream，需要写出到的目标流
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
//        //response为HttpServletResponse对象
//        response.setContentType("application/vnd.ms-excel;charset=utf-8");
//        //test.xls是弹出下载对话框的文件名，不能为中文，中文请自行编码
//        response.setHeader("Content-Disposition", "attachment;filename=历史订单列表.xls");
        ServletOutputStream out = response.getOutputStream();

        writer.flush(out, true);
        // 关闭writer，释放内存
        writer.close();
        //此处记得关闭输出Servlet流
        IoUtil.close(out);
    }

    @Override
    public AjaxResult getById(Long historyOrderId) {

        try {
            Map<String, Object> byId = xhpcHistoryOrderMapper.getById(historyOrderId);
            if (byId != null) {
                byId.putAll(getRateTime(byId.get("serialNumber").toString(), byId.get("actPrice").toString()));
            }
            return AjaxResult.success(byId);
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    @Override
    public List<Map<String, Object>> getReatTimeList(String startTime, String endTime, Long rateModelId) {

        return xhpcHistoryOrderMapper.getReatTimeList(startTime, endTime, rateModelId);
    }

    @Override
    public List<XhpcChargeHistoryOrder> getStatistisList(int number, int state) {

        return xhpcHistoryOrderMapper.getStatistisList(number, state);
    }

    @Override
    public void updateXhpcHistoryOrder(Long historyOrderId, Integer state) {

        xhpcHistoryOrderMapper.updateXhpcHistoryOrder(historyOrderId, state);
    }

    @Override
    public void addXhpcChargeOrder(String orderNo, Integer type) {
        //(调用时间-启动时间《3分钟 自动结算)
        logger.info("订单异常回调接口>>>>>orderNo：" + orderNo + "  type:" + type);
        //获取实时订单
        CacheRealtimeData cacheRealtimeData = redisService.getCacheObject("order:" + orderNo + ".lord");
        if (cacheRealtimeData != null) {
            XhpcChargeOrder xhpcChargeOrder = xhpcChargeOrderService.getSerialNumberMessage(orderNo);
            Long userId = xhpcChargeOrder.getUserId();
            try {
                //开始时间
                Date startTime2 = xhpcChargeOrder.getStartTime();
                //当checking为true时，自动结算
                Integer chargingTime = cacheRealtimeData.getChargingTime();
                boolean checking = false;
                if (type == 1) {
                    if (chargingTime < 3) {
                        checking = true;
                    }
                } else {
                    checking = true;
                }

                //毫秒
                DateTime date = DateUtil.offsetMinute(xhpcChargeOrder.getStartTime(), chargingTime);
                xhpcChargeOrder.setEndTime(date);
                xhpcChargeOrder.setUpdateTime(date);
                if (checking) {
                    xhpcChargeOrder.setStatus(3);
                } else {
                    xhpcChargeOrder.setStatus(2);
                }
                xhpcChargeOrder.setEndSoc(cacheRealtimeData.getSoc() + "");
                //充电时长
                long time = (long) (cacheRealtimeData.getChargingTime() / 1000);
                if (time > 3600) {
                    long hours = time / 3600;
                    double mins = (double) ((time - (hours * 3600)) / 60);
                    xhpcChargeOrder.setChargingTime(hours + "时" + new BigDecimal(mins).setScale(0) + "分");
                } else {
                    double mins = (double) (time / 60);
                    xhpcChargeOrder.setChargingTime(new BigDecimal(mins).setScale(0) + "分");
                }
                BigDecimal decimal = new BigDecimal(10000);
                xhpcChargeOrder.setChargingDegree(new BigDecimal(cacheRealtimeData.getChargingDegree()).divide(decimal, 2, BigDecimal.ROUND_DOWN));
                xhpcChargeOrder.setAmountCharged(new BigDecimal(cacheRealtimeData.getAmountCharged()).divide(decimal, 2, BigDecimal.ROUND_DOWN));
                xhpcChargeOrder.setChargingTimeNumber(Long.valueOf(cacheRealtimeData.getChargingTime()));


                if (checking) {
                    BigDecimal money = xhpcChargeOrder.getAmountCharged();
                    //结算
                    //总电费
                    BigDecimal powerPrice = new BigDecimal(0);
                    //算时间是否跨天
                    Long rateModelId = xhpcChargeOrder.getRateModelId();

                    Date updateTime2 = xhpcChargeOrder.getEndTime();
                    long betweenDay = DateUtil.between(startTime2, updateTime2, DateUnit.DAY);

                    if (betweenDay == 0) {
                        powerPrice = getBigDecimal(rateModelId, startTime2, updateTime2, xhpcChargeOrder.getChargingDegree());
                    } else {
                        //跨天
                        Date updateTime = DateUtil.endOfDay(startTime2);
                        powerPrice = getBigDecimal(rateModelId, startTime2, updateTime, xhpcChargeOrder.getChargingDegree());
                        //明天
                        DateTime tomorrow = DateUtil.offsetDay(startTime2, 1);
                        Date startTime3 = DateUtil.beginOfDay(tomorrow);
                        powerPrice = powerPrice.add(getBigDecimal(rateModelId, startTime3, updateTime2, xhpcChargeOrder.getChargingDegree()));
                    }

                    //总服务费
                    BigDecimal servicePrice = money.subtract(powerPrice);
                    //剩余的电费
                    BigDecimal surplusPowerPrice = powerPrice;
                    //剩余的服务费
                    BigDecimal surplusServicePrice = servicePrice;

                    Map<String, Object> userMessage = xhpcChargeOrderService.getUserMessage(userId);

                    XhpcHistoryOrder xhpcHistoryOrder = new XhpcHistoryOrder();
                    xhpcHistoryOrder.setStopReasonEvcs(5);
                    xhpcHistoryOrder.setPowerPriceTotal(powerPrice);
                    xhpcHistoryOrder.setServicePriceTotal(servicePrice);
                    xhpcHistoryOrder.setTotalPower(cacheRealtimeData.getAmountCharged().doubleValue() / 10000);
                    //电表总起值
                    //xhpcHistoryOrder.setMeterValueStartEvcs(cacheOrderData.getElectricMeterStart().doubleValue());
                    //电表总止值
                    //xhpcHistoryOrder.setMeterValueEndEvcs(cacheOrderData.getElectricMeterEnd().doubleValue());
                    //vin
                    //xhpcHistoryOrder.setVinNormal(vinNormal);
                    BigDecimal balance = new BigDecimal(userMessage.get("balance").toString()).divide(new BigDecimal(100));
                    //电站活动抵扣--抵扣的总金额
                    BigDecimal promotionDiscount = new BigDecimal(0);

                    //实际价格-用户支付的钱
                    BigDecimal actPrice = money;
                    //流量方总金额抽成
                    BigDecimal internetCommission = new BigDecimal(0);
                    //流量方服务费抽成
                    BigDecimal internetSvcCommission = new BigDecimal(0);
                    //平台总金额抽成
                    BigDecimal platformCommission = new BigDecimal(0);
                    //平台服务费抽成
                    BigDecimal platformSvcCommission = new BigDecimal(0);
                    //运维总抽成
                    BigDecimal operationCommission = new BigDecimal(0);
                    //运维服务费抽成
                    BigDecimal operationSvcCommission = new BigDecimal(0);
                    //判断是C端用户还是流量端用户
                    if (xhpcChargeOrder.getSource() == 0) {
                        String state = "";
                        BigDecimal discount = new BigDecimal(0);
                        //用户第几次充电
                        int count = xhpcChargeOrderService.getCount(userId, xhpcChargeOrder.getChargeOrderId());
                        if (count == 0) {
                            //活动折扣
                            Map<String, Object> promotion = xhpcChargeOrderService.getPromotion();
                            if (promotion != null && promotion.get("state") != null && promotion.get("discount") != null) {
                                //state 1.总金额 2.电费 3.服务费   discount 折扣率
                                state = promotion.get("state").toString();
                                discount = new BigDecimal(promotion.get("discount").toString());
                            }
                        }
                        if (!"".equals(state)) {

                            //查看是否优惠为0
                            boolean fan = discount.compareTo(new BigDecimal(0)) != 0;
                            if ("1".equals(state)) {
                                //总金额
                                if (fan) {
                                    promotionDiscount = money.multiply(discount);
                                    actPrice = money.subtract(promotionDiscount);
                                    surplusPowerPrice = surplusPowerPrice.subtract(promotionDiscount.divide(new BigDecimal(2)));
                                    surplusServicePrice = surplusServicePrice.subtract(promotionDiscount.divide(new BigDecimal(2)));
                                }
                            } else if ("2".equals(state)) {
                                if (fan) {
                                    //电费
                                    promotionDiscount = powerPrice.multiply(balance);
                                    actPrice = money.subtract(promotionDiscount);
                                    surplusPowerPrice = surplusPowerPrice.subtract(promotionDiscount);
                                }
                            } else if ("3".equals(state)) {
                                if (fan) {
                                    //服务费
                                    promotionDiscount = servicePrice.multiply(balance);
                                    actPrice = money.subtract(promotionDiscount);
                                    surplusServicePrice = surplusServicePrice.subtract(promotionDiscount);
                                }
                            }
                        }
                        xhpcHistoryOrder.setInternetCommission(internetCommission);
                        xhpcHistoryOrder.setInternetSvcCommission(internetSvcCommission);
                    } else {
                        //流量方，未实现，新增接口
                    }
                    //获取运营商
                    Map<String, Object> operatorMessage = xhpcChargeOrderService.getOperatorMessage(xhpcChargeOrder.getChargingStationId());
                    if (operatorMessage != null) {
                        if (operatorMessage.get("operatorIdEvcs") != null) {

                            if (operatorMessage.get("operatorIdEvcs") != null && !"".equals(operatorMessage.get("operatorIdEvcs").toString())) {
                                String stw = operatorMessage.get("operatorIdEvcs").toString();
                                if (stw.length() > 9) {
                                    xhpcHistoryOrder.setOperatorIdEvcs(stw.substring(8, stw.length() - 1));
                                }
                            }
                        }
                        if (operatorMessage.get("maintenanceCommissionRate") != null && operatorMessage.get("commissionType") != null && operatorMessage.get("platformCommissionRate") != null) {
                            Integer commissionType = (Integer) operatorMessage.get("commissionType");
                            //运维提成
                            BigDecimal maintenanceCommissionRate = new BigDecimal(operatorMessage.get("maintenanceCommissionRate").toString()).divide(new BigDecimal(100));
                            //平台提成
                            BigDecimal platformCommissionRate = new BigDecimal(operatorMessage.get("platformCommissionRate").toString()).divide(new BigDecimal(100));
                            //提成类型（0总金额提成 1服务费提成）
                            if (commissionType == 0) {
                                BigDecimal multiply1 = surplusPowerPrice.multiply(platformCommissionRate);
                                BigDecimal multiply2 = surplusServicePrice.multiply(platformCommissionRate);
                                platformCommission = multiply1.add(multiply2);
                                //剩下的钱
                                surplusPowerPrice = surplusPowerPrice.subtract(multiply1);
                                surplusServicePrice = surplusServicePrice.subtract(multiply2);
                                BigDecimal multiply3 = surplusPowerPrice.multiply(maintenanceCommissionRate);
                                BigDecimal multiply4 = surplusServicePrice.multiply(maintenanceCommissionRate);
                                operationCommission = multiply1.add(multiply2);
                                //剩下的钱
                                surplusPowerPrice = surplusPowerPrice.subtract(multiply3);
                                surplusServicePrice = surplusServicePrice.subtract(multiply4);

                            } else if (commissionType == 1) {
                                BigDecimal multiply2 = surplusServicePrice.multiply(platformCommissionRate);
                                platformSvcCommission = multiply2;
                                //剩下的钱
                                surplusServicePrice = surplusServicePrice.subtract(multiply2);

                                BigDecimal multiply4 = surplusServicePrice.multiply(maintenanceCommissionRate);
                                operationCommission = multiply4;
                                //剩下的钱
                                surplusServicePrice = surplusServicePrice.subtract(multiply4);
                            }
                        } else {
                            //订单异常
                            xhpcChargeOrder.setStatus(2);
                            //异常原因
                            xhpcChargeOrder.setErroRemark("运营商数据为空");
                        }
                    }

                    Long chargeOrderId = xhpcChargeOrder.getChargeOrderId();
                    xhpcHistoryOrder.setChargeOrderId(chargeOrderId);
                    xhpcHistoryOrder.setChargingStationId(xhpcChargeOrder.getChargingStationId());
                    xhpcHistoryOrder.setUserId(userId);
                    xhpcHistoryOrder.setTerminalId(xhpcChargeOrder.getTerminalId());
                    xhpcHistoryOrder.setStartTime(xhpcChargeOrder.getStartTime());
                    xhpcHistoryOrder.setStopReasonEvcs(xhpcChargeOrder.getStopReasonEvcs());//todo 从头开始设置所有evcs字段
                    xhpcHistoryOrder.setChargeModelEvcs(xhpcChargeOrder.getChargeModelEvcs());
                    xhpcHistoryOrder.setSerialNumber(xhpcChargeOrder.getSerialNumber());
                    xhpcHistoryOrder.setRateModelId(xhpcChargeOrder.getRateModelId());
                    xhpcHistoryOrder.setStartSoc(xhpcChargeOrder.getStartSoc());
                    xhpcHistoryOrder.setReconciliationStatus(0);
                    xhpcHistoryOrder.setSortingStatus(0);
                    xhpcHistoryOrder.setType(1);
                    //订单总价---运维服务费抽成
                    xhpcHistoryOrder.setTotalPrice(money.setScale(2, BigDecimal.ROUND_DOWN));
                    xhpcHistoryOrder.setPromotionDiscount(promotionDiscount.setScale(2, BigDecimal.ROUND_DOWN));
                    xhpcHistoryOrder.setActPrice(actPrice.setScale(2, BigDecimal.ROUND_DOWN));
                    xhpcHistoryOrder.setActPowerPrice(surplusPowerPrice.setScale(2, BigDecimal.ROUND_DOWN));
                    xhpcHistoryOrder.setActServicePrice(surplusServicePrice.setScale(2, BigDecimal.ROUND_DOWN));
                    xhpcHistoryOrder.setInternetCommission(internetCommission.setScale(2, BigDecimal.ROUND_DOWN));
                    xhpcHistoryOrder.setInternetSvcCommission(internetSvcCommission.setScale(2, BigDecimal.ROUND_DOWN));
                    xhpcHistoryOrder.setPlatformCommission(platformCommission.setScale(2, BigDecimal.ROUND_DOWN));
                    xhpcHistoryOrder.setPlatformSvcCommisssion(platformSvcCommission.setScale(2, BigDecimal.ROUND_DOWN));
                    xhpcHistoryOrder.setOperationCommission(operationCommission.setScale(2, BigDecimal.ROUND_DOWN));
                    xhpcHistoryOrder.setOperationSvcCommission(operationSvcCommission.setScale(2, BigDecimal.ROUND_DOWN));
                    xhpcHistoryOrder.setStartSoc(xhpcChargeOrder.getStartSoc());
                    xhpcHistoryOrder.setEndSoc(xhpcChargeOrder.getEndSoc());
                    xhpcHistoryOrder.setReconciliationStatus(0);
                    xhpcHistoryOrder.setCreateTime(new Date());
                    xhpcHistoryOrder.setChargeModelEvcs(3);
                    xhpcHistoryOrder.setUserNameEvcs(userMessage.get("phone").toString());
                    xhpcHistoryOrder.setPhone(userMessage.get("phone").toString());
                    xhpcHistoryOrder.setConnectorPowerEvcs(Double.parseDouble(xhpcChargeOrder.getPower()));


                    //扣除用户实际消费金额，添加消费记录
                    Map<String, Object> user = xhpcChargeOrderService.getUserMessage(userId);
                    //剩余的钱
                    BigDecimal balance1 = (BigDecimal) user.get("balance");
                    BigDecimal subtract = balance1.subtract(actPrice);
                    int i = xhpcChargeOrderService.updateUserBalance(userId, subtract);
                    if (i == 0) {
                        //扣钱失败
                        xhpcChargeOrder.setStatus(2);
                        xhpcChargeOrder.setErroRemark("扣钱失败");
                    } else {
                        insert(xhpcHistoryOrder);
                        //添加流水
                        xhpcChargeOrderService.addUserAccountStatement(userId, actPrice.negate(), subtract, xhpcChargeOrder.getChargeOrderId(), 3, date);
                        try {
                            Map<String, Object> xhpcChargingPile = xhpcChargeOrderService.getXhpcChargingPile(xhpcChargeOrder.getTerminalId());
                            if (xhpcChargingPile != null) {
                                //发送短信
                                if (user.get("phone") != null) {
                                    if ("1".equals(xhpcChargingPile.get("type").toString())) {
                                        HashMap<String, String> paramMap = new HashMap<>();
                                        paramMap.put("elec", xhpcChargeOrder.getEndSoc());
                                        paramMap.put("sumMoney", actPrice.toString());
                                        paramMap.put("phone", user.get("phone").toString());
                                        paramMap.put("content", "【小华停止充电】尊敬的用户，你的爱车已停止充电，电量为：" + xhpcChargeOrder.getEndSoc() + "%，总费用为：" + actPrice + "元，充电费用明细，请查询小华充电小程序，谢谢。");
                                        smsService.sendNotice(paramMap);
                                    } else {
                                        HashMap<String, String> paramMap = new HashMap<>();
                                        paramMap.put("sumMoney", actPrice.toString());
                                        paramMap.put("phone", user.get("phone").toString());
                                        paramMap.put("content", "【小华停止充电】尊敬的用户，你的爱车已停止充电，总费用为：" + actPrice + "元，充电费用明细，请查询小华充电小程序，谢谢。");
                                        smsService.sendNotice(paramMap);
                                    }
                                }
                            }
                        } catch (Exception e) {
                            logger.info("<<<<<<<<<<<<<<<<发送短信失败>>>>>>>>>>>>>>>>>");
                        }
                        // 另起线程处理业务上传redis数据
                        executorService.execute(new Runnable() {
                            @Override
                            public void run() {

                                xhpcRealTimeOrderService.addPileEndOrder(xhpcHistoryOrder, xhpcChargeOrder, xhpcChargeOrder.getSerialNumber(), 1);
                            }
                        });
                    }
                }
                xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
            } catch (Exception e) {
                logger.info("异常订单回调失败");
                e.printStackTrace();
            }
        }


    }

    @Override
    public Map<String, Object> getLandUser(Long userId) {

        return xhpcHistoryOrderMapper.getLandUser(userId);
    }

    /**
     * 历史信息费率时段
     */
    private Map<String, Object> getRateTime(String serialNumber, String actPrice) {

        BigDecimal powerPriceTotal = new BigDecimal(0);
        BigDecimal servicePriceTotal = new BigDecimal(0);
        //累计充电时间、计费模型、开始时间、结束时间、已充金额
        XhpcChargeOrder chargeOrder = xhpcChargeOrderService.getSerialNumberMessage(serialNumber);
        Long rateModelId = chargeOrder.getRateModelId();
        Date startTime2 = chargeOrder.getStartTime();
        Date updateTime2 = chargeOrder.getEndTime();
        //充电度数
        BigDecimal chargingDegree = chargeOrder.getChargingDegree();
        List<Map<String, Object>> list = new ArrayList<>();
        //1时间没有跨天
        long betweenDay = DateUtil.between(startTime2, updateTime2, DateUnit.DAY);
        if (betweenDay == 0) {
            return getBigDecimal(actPrice, powerPriceTotal, servicePriceTotal, chargeOrder, rateModelId, startTime2, updateTime2, chargingDegree, list);
        } else {
            //跨天
            Date updateTime = DateUtil.endOfDay(startTime2);
            Map<String, Object> map1 = getBigDecimal(actPrice, powerPriceTotal, servicePriceTotal, chargeOrder, rateModelId, startTime2, updateTime, chargingDegree, list);
            //获取
            BigDecimal powerPriceTotal1 = (BigDecimal) map1.get("powerPriceTotal");
            BigDecimal servicePriceTotal1 = (BigDecimal) map1.get("servicePriceTotal");
            //明天
            DateTime tomorrow = DateUtil.offsetDay(startTime2, 1);
            Date startTime3 = DateUtil.beginOfDay(tomorrow);
            Map<String, Object> map2 = getBigDecimal(actPrice, powerPriceTotal1, servicePriceTotal1, chargeOrder, rateModelId, startTime3, updateTime2, chargingDegree, list);
            return map2;
        }
    }

    private Map<String, Object> getBigDecimal(String actPrice, BigDecimal powerPriceTotal, BigDecimal servicePriceTotal, XhpcChargeOrder chargeOrder, Long rateModelId, Date startTime2, Date updateTime2, BigDecimal chargingDegree, List<Map<String, Object>> list) {

        Map<String, Object> map = new HashMap<>();
        //算出相差时间,分
        BigDecimal decimal = new BigDecimal((updateTime2.getTime() - startTime2.getTime()) / 60000).setScale(2);
        //每分钟多少度
        BigDecimal degree = chargingDegree.divide(decimal, 2, BigDecimal.ROUND_DOWN);
        //获取费率时间段
        String startTime = DateUtil.formatTime(startTime2);
        String endTime = DateUtil.formatTime(updateTime2);
        List<Map<String, Object>> reatTimeList = getReatTimeList(startTime, endTime, rateModelId);
        if (reatTimeList != null && reatTimeList.size() > 0) {
            Map<String, Object> map1 = new HashMap<>();
            int size = reatTimeList.size();
            if (size == 1) {
                BigDecimal powerFee = new BigDecimal(reatTimeList.get(0).get("powerFee").toString()).setScale(2, BigDecimal.ROUND_DOWN);
                //powerPriceTotal = powerFee.multiply(degree).setScale(2, BigDecimal.ROUND_DOWN);
                BigDecimal servicePrice = new BigDecimal(reatTimeList.get(0).get("serviceFee").toString()).setScale(2, BigDecimal.ROUND_DOWN);
                //servicePriceTotal=servicePrice.multiply(chargingDegree).setScale(2, BigDecimal.ROUND_DOWN);
                map1.put("time", startTime + "-" + endTime);
                map1.put("powerPrice", powerFee);
                map1.put("servicePrice", servicePrice);
                map1.put("chargingDegree", chargeOrder.getChargingDegree());
                map1.put("actPrice", actPrice);
                list.add(map1);
            } else {
                for (int i = 0; i < reatTimeList.size(); i++) {
                    Map<String, Object> objectMap = reatTimeList.get(i);
                    BigDecimal powerPrice = new BigDecimal(objectMap.get("powerFee").toString()).setScale(2, BigDecimal.ROUND_DOWN);
                    BigDecimal servicePrice = new BigDecimal(objectMap.get("serviceFee").toString()).setScale(2, BigDecimal.ROUND_DOWN);
                    String startTime1 = objectMap.get("startTime").toString();
                    String endTime1 = objectMap.get("endTime").toString();
                    if("00:00:00".equals(endTime1)){
                        endTime1="23:59:59";
                    }
                    if(size==1){
                        list.add(getRateTimeList(startTime, endTime, degree, powerPrice, servicePrice));
                    }else{
                        if(i==0){
                            list.add(getRateTimeList(startTime, endTime1, degree, powerPrice, servicePrice));
                        } else if(i<size-1){
                            list.add(getRateTimeList(startTime1, endTime1, degree, powerPrice, servicePrice));
                        }else{
                            list.add(getRateTimeList(startTime1, endTime, degree, powerPrice, servicePrice));
                        }
                    }
                }
            }
        }

        map.put("list", list);//数据列表
        //map.put("chargingTimeTotal",chargeOrder.getChargingTime());//总时长
        //map.put("powerPriceTotal",powerPriceTotal);//总电费单价(元/度)
        //map.put("servicePriceTotal",servicePriceTotal);//总服务费单价(元/度)
        //map.put("chargingDegreeTotal",chargeOrder.getChargingDegree());//总度数
        //map.put("actPriceTotal",actPrice);//总费用
        return map;
    }

    private Map<String, Object> getRateTimeList(String startTime, String endTime, BigDecimal degree, BigDecimal powerPrice, BigDecimal servicePrice) {

        Map<String, Object> map = new HashMap<>();
        BigDecimal v = new BigDecimal((DateUtil.parse(endTime).getTime() - DateUtil.parse(startTime).getTime()) / 60000).multiply(degree);
        BigDecimal multiply = powerPrice.add(servicePrice).multiply(v).setScale(2, BigDecimal.ROUND_DOWN);
        map.put("time", startTime + "-" + endTime);
        map.put("powerPrice", powerPrice);
        map.put("servicePrice", servicePrice);
        map.put("chargingDegree", v);
        map.put("actPrice", multiply);
        return map;
    }

    /**
     * @param rateModelId    费率id
     * @param startTime2     开始时间
     * @param updateTime2    结算时间
     * @param chargingDegree 总度数
     * @return
     */
    private BigDecimal getBigDecimal(Long rateModelId, Date startTime2, Date updateTime2, BigDecimal chargingDegree) {
        //算出相差时间,分
        BigDecimal decimal = new BigDecimal((updateTime2.getTime() - startTime2.getTime()) / 60000).setScale(2);
        //每分钟多少度
        BigDecimal degree = chargingDegree.divide(decimal, 2, BigDecimal.ROUND_DOWN);
        BigDecimal powerPriceTotal = new BigDecimal(0);
        //获取费率时间段
        String startTime = DateUtil.formatTime(startTime2);
        String endTime = DateUtil.formatTime(updateTime2);
        List<Map<String, Object>> reatTimeList = getReatTimeList(startTime, endTime, rateModelId);
        if (reatTimeList != null && reatTimeList.size() > 0) {
            int size = reatTimeList.size();
            if (size == 1) {
                BigDecimal powerFee = new BigDecimal(reatTimeList.get(0).get("powerFee").toString());
                powerPriceTotal = powerPriceTotal.add(powerFee.multiply(degree).setScale(2, BigDecimal.ROUND_DOWN));
            } else {
                for (int i = 0; i < reatTimeList.size(); i++) {
                    Map<String, Object> objectMap = reatTimeList.get(i);
                    BigDecimal powerPrice = new BigDecimal(objectMap.get("powerFee").toString());
                    String startTime1 = objectMap.get("startTime").toString();
                    String endTime1 = objectMap.get("endTime").toString();
                    if (i == 0) {
                        powerPriceTotal = powerPriceTotal.add(getRateTimeList(startTime, endTime1, degree, powerPrice));
                    } else {
                        if (size == 2) {
                            powerPriceTotal = powerPriceTotal.add(getRateTimeList(startTime, endTime, degree, powerPrice));
                        } else {
                            //三个时段以上
                            if (i < size - 1) {
                                powerPriceTotal = powerPriceTotal.add(getRateTimeList(startTime1, endTime1, degree, powerPrice));
                            } else {
                                powerPriceTotal = powerPriceTotal.add(getRateTimeList(startTime1, endTime, degree, powerPrice));

                            }
                        }
                    }
                }
            }
        }
        return powerPriceTotal;
    }

    private BigDecimal getRateTimeList(String startTime, String endTime, BigDecimal degree, BigDecimal powerPrice) {

        BigDecimal v = new BigDecimal((DateUtil.parse(endTime).getTime() - DateUtil.parse(startTime).getTime()) / 60000).multiply(degree);
        BigDecimal multiply = powerPrice.multiply(v).setScale(2, BigDecimal.ROUND_DOWN);
        return multiply;
    }

}
