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.BigExcelWriter;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson.JSON;
import com.xhpc.common.api.UserTypeService;
import com.xhpc.common.core.constant.StatusConstants;
import com.xhpc.common.core.domain.R;
import com.xhpc.common.core.utils.DateUtils;
import com.xhpc.common.core.utils.SecurityUtils;
import com.xhpc.common.core.web.domain.AjaxResult;
import com.xhpc.common.core.web.service.BaseService;
import com.xhpc.common.data.redis.CacheRealtimeData;
import com.xhpc.common.enums.StopReasonEnum;
import com.xhpc.common.redis.service.RedisService;
import com.xhpc.common.security.service.TokenService;
import com.xhpc.common.util.UserTypeUtil;
import com.xhpc.order.domain.XhpcChargeOrder;
import com.xhpc.order.domain.XhpcHistoryOrder;
import com.xhpc.order.domain.XhpcRealTimeOrder;
import com.xhpc.order.dto.*;
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 com.xhpc.system.api.domain.SysUser;
import com.xhpc.system.api.model.LoginUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.xhpc.common.core.utils.DateUtils.YYYY_MM_DD_HH_MM_SS;

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

    @Resource
    private XhpcHistoryOrderMapper xhpcHistoryOrderMapper;

    @Autowired
    private IXhpcChargeOrderService xhpcChargeOrderService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private IXhpcRealTimeOrderService xhpcRealTimeOrderService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private UserTypeService userTypeService;

    private static final Logger logger = LoggerFactory.getLogger(XhpcHistoryOrderServiceImpl.class);
    private static Map<String, String> SM = new HashMap<>();
    static {
        SM.put("40", "APP 远程停止(0X40)");
        SM.put("41", "SOC 达到 100%(0X41)");
        SM.put("42", "充电电量满足设定条件(0X42)");
        SM.put("43", "充电金额满足设定条件(0X43)");
        SM.put("44", "充电时间满足设定条件(0X44)");
        SM.put("45", "手动停止充电(0X45)");
        SM.put("4A", "充电桩控制系统故障(需要重启或自动恢复)(0X4A)");
        SM.put("4B", "控制导引断开(0X4B)");
        SM.put("4C", "断路器跳位(0X4C)");
        SM.put("4D", "电表通信中断(0X4D)");
        SM.put("4E", "余额不足(0X4E)");
        SM.put("4F", "充电模块故障(0X4F)");
        SM.put("50", "急停开入(0X50)");
        SM.put("51", "防雷器异常(0X5)");
        SM.put("52", "BMS 未就绪(0X52)");
        SM.put("53", "温度异常(0X53)");
        SM.put("54", "电池反接故障(0X54)");
        SM.put("55", "电子锁异常(0X55)");
        SM.put("56", "合闸失败(0X56)");
        SM.put("57", "绝缘异常(0X57)");
        SM.put("59", "接收 BMS 握手报文 BHM 超时(0X59)");
        SM.put("5A", "接收 BMS 和车辆的辨识报文超时 BRM(0X5A)");
        SM.put("5B", "接收电池充电参数报文超时 BCP(0X5B)");
        SM.put("5C", "接收 BMS 完成充电准备报文超时 BRO AA(0X5C)");
        SM.put("5D", "接收电池充电总状态报文超时 BCS(0X5D)");
        SM.put("5E", "接收电池充电要求报文超时 BCL(0X5E)");
        SM.put("5F", "接收电池状态信息报文超时 BSM(0X5F)");
        SM.put("60", "GB2015 电池在BHM 阶段有电压不允许充电(0X60)");
        SM.put("61", "GB2015 辨识阶段在 BRO_AA 时候电池实际电压与 BCP 报文电池电压差距大于 5%(0X61)");
        SM.put("62", "B2015 充电机在预充电阶段从 BRO_AA 变成BRO_00 状态(0X62)");
        SM.put("63", "接收主机配置报文超时(0X63)");
        SM.put("64", "充电机未准备就绪,我们没有回 CRO AA，对应老国标(0X64)");
        SM.put("6A", "系统闭锁(0X6A)");
        SM.put("6B", "导引断开(0X6B)");
        SM.put("6C", "断路器跳位(0X6C)");
        SM.put("6D", "电表通信中断(0X6D)");
        SM.put("6E", "余额不足(0X6E)");
        SM.put("6F", "交流保护动作(0X6F)");
        SM.put("70", "直流保护动作(0X70)");
        SM.put("71", "充电模块故障(0X71)");
        SM.put("72", "急停按钮停止充电(0X72)");
        SM.put("73", "防雷器异常(0X73)");
        SM.put("74", "温度异常(0X74)");
        SM.put("75", "输出异常(0X75)");
        SM.put("76", "充电无流(0X76)");
        SM.put("77", "电子锁异常(0X77)");
        SM.put("78", "预留(0X78)");
        SM.put("79", "总充电电压异常(0X79)");
        SM.put("7A", "总充电电流异常(0X7A)");
        SM.put("7B", "单体充电电压异常(0X7B)");
        SM.put("7C", "电池组过温(0X7C)");
        SM.put("7D", "最高单体充电电压异常(0X7D)");
        SM.put("7E", "最高电池组过温(0X7E)");
        SM.put("7F", "BMV 单体充电电压异常(0X7F)");
        SM.put("80", "BMT 电池组过温(0X80)");
        SM.put("81", "电池状态异常停止充电(0X81)");
        SM.put("82", "车辆发报文禁止充电(0X82)");
        SM.put("83", "充电桩断电(0X83)");
        SM.put("84", "接收电池充电总状态报文超时(0X84)");
        SM.put("85", "接收电池充电要求报文超时(0X85)");
        SM.put("86", "接收电池状态信息报文超时(0X86)");
        SM.put("87", "接收 BMS 中止充电报文超时(0X87)");
        SM.put("88", "接收 BMS 充电统计报文超时(0X88)");
        SM.put("89", "接收对侧 CCS 报文超时(0X89)");
        SM.put("90", "未知原因中止(0X90)");
        SM.put("91", "平台结算(0X91)");
        SM.put("92", "远程重启(0X92)");
        SM.put("93", "远程更新应答(0X93)");
        SM.put("94", "远程更新(0X94)");
        SM.put("199", "平台空订单(0X199)");
    }



    @Override
    public List<Map<String, Object>> list(HttpServletRequest request) {
        List<Map<String, Object>> list =new ArrayList<>();
        LoginUser loginUser = tokenService.getLoginUser(request);
        startPage();
        if(loginUser==null){
            return list;
        }
        Long userid = loginUser.getUserid();
        String tenantId = loginUser.getTenantId();
        Integer userType = loginUser.getUserType();

//        R user = userTypeService.getUser(null, userid, userType, null, tenantId);
//
//        if(user !=null && user.getData() !=null){
//            Map<String, Object> userMessage = (Map<String, Object>)user.getData();
//            if (userMessage != null) {
//                startPage();
//                return xhpcHistoryOrderMapper.list(userid,userType,tenantId);
//            }
//        }

      //  List<Map<String, Object>> list1 = xhpcHistoryOrderMapper.list(userid, userType, tenantId);

        return  xhpcHistoryOrderMapper.list(userid, userType, tenantId);
    }

    @Override
    public int update(XhpcHistoryOrder xhpcHistoryOrder) {

        return xhpcHistoryOrderMapper.update(xhpcHistoryOrder);
    }

    @Override
    public AjaxResult gethistotyOrderMessage(HttpServletRequest request, Long userId, Long historyOrderId, Integer type, Long chargingOrderId) {
        LoginUser loginUser = tokenService.getLoginUser(request);

        Map<String, Object> map = xhpcHistoryOrderMapper.gethistotyOrderMessage(loginUser.getUserid(), historyOrderId, loginUser.getUserType(), chargingOrderId, loginUser.getTenantId());
        if(map !=null){
            if(map.get("typeName") !=null){
                map.put("typeName",translate(map.get("typeName").toString()));
            }
            return AjaxResult.success(map);
        }
        //查询最后一帧数据
        if(chargingOrderId !=null){
            Map<String, Object> stringObjectMap = xhpcHistoryOrderMapper.getchargingOrderById(chargingOrderId,loginUser.getUserid(),loginUser.getUserType(),loginUser.getTenantId());
            if(stringObjectMap !=null){
                //获取该订单最后一条实时数据
                Map<String, Object> cacheMap = redisService.getCacheMap("order:" + stringObjectMap.get("serialNumber").toString());
                List<CacheRealtimeData> list = (List<CacheRealtimeData>) cacheMap.get("realtimeDataList");
                CacheRealtimeData startData =new CacheRealtimeData();
                CacheRealtimeData endData =new CacheRealtimeData();

                Date startTime = null;
                Date endTime = null;
                BigDecimal amountCharged = new BigDecimal(0);
                //充电度数
                BigDecimal chargingDegree = new BigDecimal(0);
                if (list != null && list.size() > 0) {
                    endData =list.get(list.size()-1);
                    for (int i = 0; i <list.size() ; i++) {
                        startData =list.get(i);
                        if(startData.getSoc()>0){
                            break;
                        }
                    }
                }
                Long rateModelId = Long.valueOf(stringObjectMap.get("rateModelId").toString());
                if(endData !=null && endData.getAmountCharged() !=null){
                    //最后一祯时间
                     endTime = DateUtil.parse(endData.getCreateTime());
                     startTime =DateUtil.parse(startData.getCreateTime());
                    //充电时长
                    Long tiem = (endTime.getTime() - startTime.getTime()) / 1000;
                    if (tiem > 3600) {
                        long hours = tiem / 3600;
                        double mins = (double) ((tiem - (hours * 3600)) / 60);
                        stringObjectMap.put("chargingTime",hours + "时" + new BigDecimal(mins).setScale(0) + "分");
                    } else {
                        double mins = (double) (tiem / 60);
                        stringObjectMap.put("chargingTime",new BigDecimal(mins).setScale(0) + "分");
                    }
                    chargingDegree = new BigDecimal(endData.getChargingDegree()).divide(new BigDecimal(10000), 2, BigDecimal.ROUND_HALF_UP);
                    stringObjectMap.put("chargingDegree",chargingDegree);
                    amountCharged = new BigDecimal(endData.getAmountCharged()).divide(new BigDecimal(10000),2,BigDecimal.ROUND_HALF_UP);
                    stringObjectMap.put("actPrice",amountCharged);
                }else{
                    //当没有缓存数据时，查询数据库
                    XhpcRealTimeOrder startRealTimeOrder = xhpcRealTimeOrderService.getChargingOrderId(chargingOrderId, 1);
                    XhpcRealTimeOrder endRealTimeOrder = xhpcRealTimeOrderService.getChargingOrderId(chargingOrderId, 2);
                    if(startRealTimeOrder==null || endRealTimeOrder==null){
                        return AjaxResult.success();
                    }
                    //最后一祯时间
                    endTime = endRealTimeOrder.getCreateTime();
                    startTime = startRealTimeOrder.getCreateTime();
                    chargingDegree = endRealTimeOrder.getChargingDegree();
                    stringObjectMap.put("chargingDegree",chargingDegree);
                    stringObjectMap.put("chargingTime",endRealTimeOrder.getChargingTime());
                    amountCharged=endRealTimeOrder.getAmountCharged();
                    stringObjectMap.put("actPrice",amountCharged);
                }
                BigDecimal powerPriceTotal =new BigDecimal(0);
                //1时间没有跨天
                DateTime parse = DateUtil.parse(DateUtil.format(startTime, "yyyy-MM-dd"), "yyyy-MM-dd");
                DateTime parse1 = DateUtil.parse(DateUtil.format(endTime, "yyyy-MM-dd"), "yyyy-MM-dd");
                //每分钟多少度电
                BigDecimal decimal = new BigDecimal((endTime.getTime() - startTime.getTime())).divide(new BigDecimal(60000),4,BigDecimal.ROUND_HALF_UP);
                BigDecimal divide =new BigDecimal(0);
                if(decimal.compareTo(new BigDecimal(0))==1){
                    divide=chargingDegree.divide(decimal,4,BigDecimal.ROUND_HALF_UP);
                }
                long betweenDay = DateUtil.between(parse,parse1, DateUnit.DAY);
                if(betweenDay==0){
                    powerPriceTotal = getBigDecimal(rateModelId,DateUtil.formatTime(startTime), DateUtil.formatTime(endTime), powerPriceTotal, divide);
                }else{
                    //跨天
                    powerPriceTotal = getBigDecimal(rateModelId, DateUtil.formatTime(startTime), "23:59:59", powerPriceTotal, divide);
                    System.out.println(">>>>>>跨天前>>>>>>>"+powerPriceTotal);
                    //明天
                    DateTime tomorrow = DateUtil.offsetDay(startTime,1);
                    Date startTime3 = DateUtil.beginOfDay(tomorrow);
                    powerPriceTotal = getBigDecimal(rateModelId,  DateUtil.formatTime(startTime3), DateUtil.formatTime(endTime), powerPriceTotal, divide);
                    System.out.println(">>>>>>跨天后>>>>>>>"+powerPriceTotal);
                }
                stringObjectMap.put("actPowerPrice",powerPriceTotal);

                if(stringObjectMap.get("typeName") !=null){
                    map.put("typeName",translate(map.get("typeName").toString()));
                }

            }
            return AjaxResult.success(stringObjectMap);
        }
        return AjaxResult.success();
    }

    @Override
    public void insert(XhpcHistoryOrder xhpcHistoryOrder) {

        xhpcHistoryOrderMapper.insert(xhpcHistoryOrder);
    }

    @Override
    public void insertXhpcWorkHistoryOrderDto(XhpcWorkHistoryOrderDto xhpcWorkHistoryOrderDto) {
        xhpcHistoryOrderMapper.insertXhpcWorkHistoryOrderDto(xhpcWorkHistoryOrderDto);
    }

    @Override
    public int updateXhpcHistoryOrderSerialNumber(XhpcHistoryOrder xhpcHistoryOrder) {
        return xhpcHistoryOrderMapper.updateXhpcHistoryOrderSerialNumber(xhpcHistoryOrder);
    }

    @Override
    public int updateXhpcHistoryOrderParkingVoucher(XhpcHistoryOrder xhpcHistoryOrder) {
        return xhpcHistoryOrderMapper.updateXhpcHistoryOrderParkingVoucher(xhpcHistoryOrder);
    }

    @Override
    public List<Map<String, Object>> getListPage(String tenantId,Long chargingStationId,Long chargingPileId,Long terminalId, 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,Long personnelId,Integer confirmResult,String mark) {

        Integer number = 0;
        //电话和用户类型都不为null  number =3
        //电话不为null，用户类型为null  number =1
        //电话为null，用户类型不为null  number=2
        //电话为null，用户类型为null  number=0
        if (!"".equals(phone) && phone != null && !"".equals(source) && source != null) {
            number = 3;
        } else if (!"".equals(phone) && phone != null && source==null) {
            number = 1;
        } else if(phone == null && source !=null) {
            number = 2;
        }
        //获取登陆用户
        Long logUserId = SecurityUtils.getUserId();
        LoginUser loginUser = tokenService.getLoginUser();
        SysUser sysUser = loginUser.getSysUser();
        //桩的统计、该时段金额
        List<Map<String, Object>> list = new ArrayList<>();
        if (loginUser.getUserid() != UserTypeUtil.USER_ID) {
            Map<String, Object> landUser = xhpcHistoryOrderMapper.getLandUser(loginUser.getUserid());
            if (landUser != null) {
                if (landUser.get("userType") != null) {
                    startPage();
                    if (UserTypeUtil.SYS_USER_TYPE_ONE.equals(sysUser.getUserType()) && StatusConstants.OPERATION_POWER_TYPE.equals(sysUser.getDataPowerType())) {
                        Long logOperatorId = Long.valueOf(landUser.get("operatorId").toString());
                        //运营商看自己的场站
                        list = xhpcHistoryOrderMapper.getListPage(chargingStationId,chargingPileId,terminalId,phone, transactionNumber, 1, chargingStationName, operatorId, source, beginStartTime, beginEndTime, logOperatorId, type, number,affiliationOrganization,evcsOrderNo,plateNum,internetId,internetSerialNumber,terminalName,vinCode,overStartTime,overEndTime,personnelId,confirmResult,tenantId,0,mark);
                    }else if (UserTypeUtil.SYS_USER_TYPE_TWO.equals(sysUser.getUserType()) && StatusConstants.INTERNET_POWER_TYPE.equals(sysUser.getDataPowerType())) {
                        Long logOperatorId = sysUser.getInternetUserId();
                        //流量方
                        list = xhpcHistoryOrderMapper.getListPage(chargingStationId,chargingPileId,terminalId,phone, transactionNumber, 3, chargingStationName, operatorId, source, beginStartTime, beginEndTime, logOperatorId, type, number,affiliationOrganization,evcsOrderNo,plateNum,internetId,internetSerialNumber,terminalName,vinCode,overStartTime,overEndTime,personnelId,confirmResult,tenantId,0,mark);
                    }else if (UserTypeUtil.SYS_MOTORCADE_TYPE_FOUR.equals(sysUser.getUserType()) && StatusConstants.MOTORCADE_TYPE.equals(sysUser.getDataPowerType())) {
                        Long logOperatorId = sysUser.getInternetUserId();
                        //车队
                        list = xhpcHistoryOrderMapper.getListPage(chargingStationId,chargingPileId,terminalId,phone, transactionNumber, 4, chargingStationName, operatorId, source, beginStartTime, beginEndTime, logOperatorId, type, number,affiliationOrganization,evcsOrderNo,plateNum,internetId,internetSerialNumber,terminalName,vinCode,overStartTime,overEndTime,personnelId,confirmResult,tenantId,0,mark);
                    } else {
                        //查询赋值的场站
                        list = xhpcHistoryOrderMapper.getListPage(chargingStationId,chargingPileId,terminalId,phone, transactionNumber, 2, chargingStationName, operatorId, source, beginStartTime, beginEndTime, logUserId, type, number,affiliationOrganization,evcsOrderNo,plateNum,internetId,internetSerialNumber,terminalName,vinCode,overStartTime,overEndTime,personnelId,confirmResult,tenantId,0,mark);
                    }
                }
            }

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


    @Override
    public void export(HttpServletResponse response,String tenantId,Long chargingStationId,Long chargingPileId,Long terminalId, 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,Long personnelId,Integer confirmResult,String mark) throws IOException {

        Integer number = 0;
        //电话和用户类型都不为null  number =3
        //电话不为null，用户类型为null  number =1
        //电话为null，用户类型不为null  number=2
        //电话为null，用户类型为null  number=0
        if (!"".equals(phone) && phone != null && !"".equals(source) && source != null) {
            number = 3;
        } else if (!"".equals(phone) && phone != null && source==null) {
            number = 1;
        } else if(phone == null && source !=null) {
            number = 2;
        }
        //获取登陆用户
        Long logUserId = SecurityUtils.getUserId();
        LoginUser loginUser = tokenService.getLoginUser();
        SysUser sysUser = loginUser.getSysUser();
        Long sysUserId = sysUser.getUserId();

        //桩的统计、该时段金额
        List<Map<String, Object>> list = new ArrayList<>();
        if (userId != UserTypeUtil.USER_ID) {
            if (UserTypeUtil.SYS_USER_TYPE_ONE.equals(sysUser.getUserType()) && StatusConstants.OPERATION_POWER_TYPE.equals(sysUser.getDataPowerType())) {
                Long logOperatorId = Long.valueOf(sysUser.getOperatorId());
                //运营商看自己的场站
                list = xhpcHistoryOrderMapper.getListPage(chargingStationId,chargingPileId,terminalId,phone, transactionNumber, 1, chargingStationName, operatorId, source, beginStartTime, beginEndTime, logOperatorId, type, number,affiliationOrganization,evcsOrderNo,plateNum,internetId,internetSerialNumber,terminalName,vinCode,overStartTime,overEndTime,personnelId,confirmResult,tenantId,0,mark);
            }else if (UserTypeUtil.SYS_USER_TYPE_TWO.equals(sysUser.getUserType()) && StatusConstants.INTERNET_POWER_TYPE.equals(sysUser.getDataPowerType())) {
                Long logOperatorId = sysUser.getInternetUserId();
                //流量方
                list = xhpcHistoryOrderMapper.getListPage(chargingStationId,chargingPileId,terminalId,phone, transactionNumber, 3, chargingStationName, operatorId, source, beginStartTime, beginEndTime, logOperatorId, type, number,affiliationOrganization,evcsOrderNo,plateNum,internetId,internetSerialNumber,terminalName,vinCode,overStartTime,overEndTime,personnelId,confirmResult,tenantId,0,mark);
            }else if (UserTypeUtil.SYS_MOTORCADE_TYPE_FOUR.equals(sysUser.getUserType()) && StatusConstants.MOTORCADE_TYPE.equals(sysUser.getDataPowerType())) {
                Long logOperatorId = sysUser.getInternetUserId();
                //车队
                list = xhpcHistoryOrderMapper.getListPage(chargingStationId,chargingPileId,terminalId,phone, transactionNumber, 4, chargingStationName, operatorId, source, beginStartTime, beginEndTime, logOperatorId, type, number,affiliationOrganization,evcsOrderNo,plateNum,internetId,internetSerialNumber,terminalName,vinCode,overStartTime,overEndTime,personnelId,confirmResult,tenantId,0,mark);
            } else {
                //查询赋值的场站
                list = xhpcHistoryOrderMapper.getListPage(chargingStationId,chargingPileId,terminalId,phone, transactionNumber, 2, chargingStationName, operatorId, source, beginStartTime, beginEndTime, logUserId, type, number,affiliationOrganization,evcsOrderNo,plateNum,internetId,internetSerialNumber,terminalName,vinCode,overStartTime,overEndTime,personnelId,confirmResult,tenantId,0,mark);
            }
        } else {
            list = xhpcHistoryOrderMapper.getListPage(chargingStationId,chargingPileId,terminalId,phone, transactionNumber, 0, chargingStationName, operatorId, source, beginStartTime, beginEndTime, userId, type, number,affiliationOrganization,evcsOrderNo,plateNum,internetId,internetSerialNumber,terminalName,vinCode,overStartTime,overEndTime,personnelId,confirmResult,tenantId,1,mark);
        }

        Map<String, String> reasonMap = StopReasonEnum.getMap();
        list.stream().forEach(map->map.put("stopReasonEvcsStr", reasonMap.get(map.get("stopReasonEvcs"))));

        // 通过工具类创建writer，默认创建xls格式
        BigExcelWriter writer = ExcelUtil.getBigWriter("HistoryOrder_" + System.currentTimeMillis() + ".xlsx");
        writer.addHeaderAlias("historyOrderId", "历史订单ID");
        writer.addHeaderAlias("serialNumber", "订单号");
        writer.addHeaderAlias("internetSerialNumber", "流量方订单号");
        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("powerPriceTotal", "总电费");
        writer.addHeaderAlias("servicePriceTotal", "总服务费");
        writer.addHeaderAlias("totalPrice", "订单总价");
        writer.addHeaderAlias("activityPowerPriceTotal", "活动总电费");
        writer.addHeaderAlias("activityServicePriceTotal", "活动总服务费");
        writer.addHeaderAlias("activityTotalPrice", "活动总金额");
        writer.addHeaderAlias("promotionDiscount", "电站活动抵扣总金额");
        writer.addHeaderAlias("actPrice", "实际用户支付金额");
        writer.addHeaderAlias("internetCommission", "流量方总金额抽成");
        writer.addHeaderAlias("internetSvcCommission", "流量方服务费抽成");
        writer.addHeaderAlias("internetDegreeCommission", "流量方电量抽成");
        writer.addHeaderAlias("platformCommission", "平台总金额抽成");
        writer.addHeaderAlias("platformSvcCommisssion", "平台服务费抽成");
        writer.addHeaderAlias("operationCommission", "运维总抽成");
        writer.addHeaderAlias("operationSvcCommission", "运维服务费抽成");
        writer.addHeaderAlias("actPowerPrice", "运营商电费");
        writer.addHeaderAlias("actServicePrice", "运营商服务费");
        writer.addHeaderAlias("actSumPrice", "运营商总金额");
//        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("chargingModeName", "订单来源");
        writer.addHeaderAlias("stopReasonEvcs", "停止原因代码");
        writer.addHeaderAlias("stopReasonEvcsStr", "停止原因说明");
        writer.addHeaderAlias("sourceName", "用户类型");
        writer.addHeaderAlias("vinCode", "VIN码");
        writer.addHeaderAlias("plateNum", "车牌");
//        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) {
                if(byId.get("stopReasonRvcsName") !=null){
                    byId.put("stopReasonRvcsName",translate(byId.get("stopReasonRvcsName").toString()));
                }

                //获取历史订单收费明细
                List<Map<String, Object>> list = xhpcHistoryOrderMapper.getXhpcHistoryOrderChargeDetailsList(historyOrderId);
                if(list==null || list.isEmpty()){
                    Map<String, Object> map1 = new HashMap<>();
                    map1.put("time","00:00:00 至 00:00:00");
                    map1.put("powerPrice", 0);
                    map1.put("servicePrice", 0);
                    map1.put("chargingDegree", 0);
                    map1.put("actPrice", 0);
                    list.add(map1);
                }
                byId.put("list", list);//数据列表

//                Map<String, Object> rateTime = getRateTime(byId.get("serialNumber").toString(), byId.get("totalPrice").toString(), byId.get("totalPower").toString());
//                if(rateTime !=null){
//                    byId.putAll(rateTime);
//                }
            }
            return AjaxResult.success(byId);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }

    @Override
    public XhpcHistoryOrder getHistoryOrderById(Long historyOrderId,String serialNumber) {
        return xhpcHistoryOrderMapper.getHistoryOrderById(historyOrderId,serialNumber);
    }

    @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);
    }

    /**
     * 获取为统计的历史订单
     *
     * @param number
     * @return
     */
    @Override
    public List<XhpcChargeHistoryOrder> getNoStatisticsOrderTime(int number) {
        return xhpcHistoryOrderMapper.getNoStatisticsOrderTime(number);
    }

    /**
     * 获取为统计的历史订单（日期、电站）
     *
     * @param number
     * @return
     */
    @Override
    public List<XhpcChargeHistoryOrder> getNoStatisticsOrderDay(int number) {
        return xhpcHistoryOrderMapper.getNoStatisticsOrderDay(number);
    }

    /**
     * 获取为统计的历史订单
     *
     * @param number
     * @return
     */
    @Override
    public List<XhpcChargeHistoryOrder> getNoStatisticsOrder(int number) {
        return xhpcHistoryOrderMapper.getNoStatisticsOrder(number);
    }

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

        xhpcHistoryOrderMapper.updateXhpcHistoryOrder(historyOrderId, state);
    }

    @Override
    public void addXhpcChargeOrder(Long realTimeOrderId,Long chargeOrderId) {
        //(调用时间-启动时间《3分钟 自动结算)
        logger.info("订单异常回调接口>>>>>realTimeOrderId：" + realTimeOrderId + "  chargeOrderId:" + chargeOrderId);
        Map<String, Object> map = xhpcRealTimeOrderService.getExamineMessage(realTimeOrderId,chargeOrderId);
        if(map !=null){
            BigDecimal powerPriceTotal = new BigDecimal(map.get("powerPriceTotal").toString());
            BigDecimal servicePriceTotal = new BigDecimal(map.get("servicePriceTotal").toString());
            BigDecimal chargingDegree = new BigDecimal(map.get("chargingDegree").toString());
            if(map.get("startTime")!=null && map.get("endTime")!=null){
                xhpcRealTimeOrderService.getExamine(chargeOrderId,powerPriceTotal,servicePriceTotal,chargingDegree,map.get("startTime").toString(),map.get("endTime").toString());
            }else{
                xhpcRealTimeOrderService.getExamine(chargeOrderId,powerPriceTotal,servicePriceTotal,chargingDegree,map.get("createTime").toString(),map.get("createTime").toString());
            }
        }
    }

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

        return xhpcHistoryOrderMapper.getLandUser(userId);
    }

    @Override
    public List<Map<String, Object>> getToday() {


        LoginUser loginUser = tokenService.getLoginUser();
        Long logUserId = loginUser.getUserid();
        SysUser sysUser = loginUser.getSysUser();
        Long sysUserId = sysUser.getUserId();
        Date date = new Date();
        Date beginOfDay = DateUtil.beginOfDay(date);
        String time = DateUtil.formatDateTime(DateUtil.offsetDay(beginOfDay, -30));
        String tenantId = loginUser.getTenantId();

        int internetNumber =0;
        if(tenantId !=null && !"".equals(tenantId)){
            if(UserTypeUtil.SYS_USER_TYPE_FOUR.equals(sysUser.getUserType())){
                //运维管理人员
                internetNumber= xhpcHistoryOrderMapper.getToday(3,logUserId,time,tenantId);

            }else{
                if(sysUser.getUserId() !=UserTypeUtil.USER_ID){
                    Long logOperatorId = sysUser.getOperatorId();
                    if ("01".equals(sysUser.getUserType())) {
                        internetNumber= xhpcHistoryOrderMapper.getToday(1,logUserId,time,tenantId);
                        //运营商看自己的场站
                    }else{
                        //查询赋值的场站
                        internetNumber= xhpcHistoryOrderMapper.getToday(2,logUserId,time,tenantId);
                    }
                }else{
                    //全部桩
                    internetNumber= xhpcHistoryOrderMapper.getToday(0,logUserId,time,null);
                }
            }
        }
        int chengDuShiNUmber = xhpcHistoryOrderMapper.getChengDuShiToday();
        List<Map<String, Object>> list =new ArrayList<>();
        Map<String, Object> map =new HashMap<>();
        map.put("name","流量方未推送订单量");
        map.put("value",internetNumber);
        list.add(map);
        Map<String, Object> map1 =new HashMap<>();
        map1.put("name","成都监管平台未推送订单量");
        map1.put("value",chengDuShiNUmber);
        list.add(map1);
        return list;
    }

    @Override
    public List<Map<String, Object>> getConfirmResultPage(Integer status) {

        List<Map<String, Object>> list =new ArrayList<>();
        LoginUser loginUser = tokenService.getLoginUser();
        Long logUserId = loginUser.getUserid();
        SysUser sysUser = loginUser.getSysUser();
        String tenantId = loginUser.getTenantId();

        int internetNumber =0;
        if(tenantId !=null && !"".equals(tenantId)){
            if(UserTypeUtil.SYS_USER_TYPE_FOUR.equals(sysUser.getUserType())){
                //运维管理人员
                startPage();
                list= xhpcHistoryOrderMapper.getConfirmResultPage(status,3,logUserId,tenantId);

            }else{
                if(sysUser.getUserId() !=UserTypeUtil.USER_ID){
                    Long logOperatorId = sysUser.getOperatorId();
                    startPage();
                    if ("01".equals(sysUser.getUserType())) {
                        list= xhpcHistoryOrderMapper.getConfirmResultPage(status,1,logOperatorId,tenantId);
                        //运营商看自己的场站
                    }else{
                        //查询赋值的场站
                        list= xhpcHistoryOrderMapper.getConfirmResultPage(status,2,logUserId,tenantId);
                    }
                }else{
                    startPage();
                    //全部桩
                    list= xhpcHistoryOrderMapper.getConfirmResultPage(status,0,logUserId,null);
                }
            }
        }
        return list;

    }

    @Override
    public AjaxResult updateOrderConfirmResult(Long historyOrderId) {
        int i = xhpcHistoryOrderMapper.updateOrderConfirmResult(historyOrderId);
        if(i>0){
            return AjaxResult.success();
        }
        return AjaxResult.error("修改推送订单失败请联系管理员");
    }

    @Override
    public AjaxResult updateOrderInternetPush(Long historyOrderId) {
        int i = xhpcHistoryOrderMapper.updateOrderInternetPush(historyOrderId);
        if(i>0){
            return AjaxResult.success();
        }
        return AjaxResult.error("修改推送订单失败请联系管理员");
    }
    @Override
    public AjaxResult cancelOrders(Long historyOrderId) {
        int i = xhpcHistoryOrderMapper.cancelOrders(historyOrderId);
        if(i>0){
            return AjaxResult.success();
        }
        return AjaxResult.error("修改推送订单失败请联系管理员");
    }

    @Override
    public AjaxResult updateChengDuPush(Long historyOrderId) {
        int i = xhpcHistoryOrderMapper.updateChengDuPush(historyOrderId);
        if(i>0){
            return AjaxResult.success();
        }
        return AjaxResult.error("修改推送订单失败请联系管理员");
    }

    @Override
    public Map<String, Object> getXhpcRateTimeFee(Long rateModelId) {
        String tiem = DateUtil.formatTime(new Date());
        return xhpcHistoryOrderMapper.getXhpcRateTimeFee(tiem,rateModelId);
    }

    @Override
    public R fileUpload(HttpServletRequest request, HttpServletResponse response, String tenantId, MultipartFile file, int type, String startTime, String endTime) throws Exception {

        return null;

    }

    @Override
    public List<Map<String, Object>> getTerminalListPage(HttpServletRequest request, Long terminalId,Long chargingStationId) {
        //获取登陆用户
        Long logUserId = SecurityUtils.getUserId();
        LoginUser loginUser = tokenService.getLoginUser(request);
        //桩的统计、该时段金额
        List<Map<String, Object>> list = new ArrayList<>();
        Long userId = loginUser.getUserid();
        SysUser sysUser = loginUser.getSysUser();
        if(UserTypeUtil.SYS_USER_TYPE_FOUR.equals(sysUser.getUserType())){
            //运维管理人员
            startPage();
            list = xhpcHistoryOrderMapper.getTerminalListPage(terminalId, 2,  logUserId,chargingStationId);
        }else{
            if(UserTypeUtil.SYS_SUPER_TYPE_ONE == loginUser.getSuperType()){
                list = xhpcHistoryOrderMapper.getTerminalListPage(terminalId, 0, userId,chargingStationId);
            }else{
                if(!UserTypeUtil.SYS_USER_TYPE_ADMIN.equals(sysUser.getUserId())){
                    startPage();
                    if(UserTypeUtil.SYS_USER_TYPE_ONE.equals(sysUser.getUserType())){
                        Long logOperatorId = sysUser.getOperatorId();
                        list = xhpcHistoryOrderMapper.getTerminalListPage(terminalId, 1,  logOperatorId,chargingStationId);
                    }else{
                        //查询赋值的场站
                        list = xhpcHistoryOrderMapper.getTerminalListPage(terminalId, 2,  logUserId,chargingStationId);
                    }
                }else{
                    startPage();
                    list = xhpcHistoryOrderMapper.getTerminalListPage(terminalId, 0, userId,chargingStationId);
                }
            }
        }
        for (int i = 0; i <list.size() ; i++) {
            Map<String, Object> map = list.get(i);
            if(map!=null){
                map.put("stopReasonRvcsName",translate(map.get("stopReasonEvcs").toString()));
            }
        }

        return list;
    }

    @Override
    public AjaxResult getOrderMassageOrRateTime(String serialNumber) {
        Map<String, Object> map =new HashMap<>();
        XhpcHistoryOrder xhpcHistoryOrder = xhpcHistoryOrderMapper.getOrderMassageOrRateTime(serialNumber);

        if(xhpcHistoryOrder !=null){
            Map<String, Object> map1=new HashMap<>();
            map1.put("connectorID",xhpcHistoryOrder.getSerialNumber().substring(0, 16));
            map1.put("StartChargeSeq",xhpcHistoryOrder.getInternetSerialNumber());
            map1.put("SerialNumber",xhpcHistoryOrder.getSerialNumber());
            map1.put("EndTime",date2String(xhpcHistoryOrder.getEndTime(), "yyyy-MM-dd HH:mm:ss"));
            map1.put("StartTime",date2String(xhpcHistoryOrder.getStartTime(), "yyyy-MM-dd HH:mm:ss"));
            map1.put("ChargeModel",xhpcHistoryOrder.getChargeModelEvcs());
            map1.put("TotalPower",xhpcHistoryOrder.getTotalPower());
            map1.put("TotalElecMoney",xhpcHistoryOrder.getPowerPriceTotal().doubleValue());
            map1.put("TotalSeviceMoney",xhpcHistoryOrder.getServicePriceTotal().doubleValue());
            map1.put("TotalMoney",xhpcHistoryOrder.getTotalPrice().doubleValue());
            if(xhpcHistoryOrder.getStopReasonEvcs() !=null){
                String stopReasonEvcs = xhpcHistoryOrder.getStopReasonEvcs();
                if("40".equals(stopReasonEvcs)||"0".equals(stopReasonEvcs)||"00".equals(stopReasonEvcs)||"45".equals(stopReasonEvcs)||"APP 远程停止".equals(stopReasonEvcs)
                        ||"72".equals(stopReasonEvcs)){
                    map1.put("StopReason",0);
                }else if("41".equals(stopReasonEvcs) ||"42".equals(stopReasonEvcs)||"43".equals(stopReasonEvcs)||"44".equals(stopReasonEvcs)||"4E".equals(stopReasonEvcs)||"平台停止".equals(stopReasonEvcs)){
                    map1.put("StopReason",1);
                }else if("4A".equals(stopReasonEvcs) ||"4B".equals(stopReasonEvcs)||"4C".equals(stopReasonEvcs)||"4D".equals(stopReasonEvcs)||"4F".equals(stopReasonEvcs) ||
                        "55".equals(stopReasonEvcs)||"57".equals(stopReasonEvcs)||"62".equals(stopReasonEvcs)||"63".equals(stopReasonEvcs)||"74".equals(stopReasonEvcs)||"75".equals(stopReasonEvcs)
                        ||"78".equals(stopReasonEvcs)||"79".equals(stopReasonEvcs)||"7A".equals(stopReasonEvcs)||"7B".equals(stopReasonEvcs)||"7C".equals(stopReasonEvcs)||"7D".equals(stopReasonEvcs)
                        ||"7E".equals(stopReasonEvcs)||"7F".equals(stopReasonEvcs)||"83".equals(stopReasonEvcs)){
                    map1.put("StopReason",3);
                }else if("5A".equals(stopReasonEvcs)||"82".equals(stopReasonEvcs)){
                    map1.put("StopReason",2);
                }else if("6B".equals(stopReasonEvcs) ||"6D".equals(stopReasonEvcs)||"5E".equals(stopReasonEvcs)){
                    map1.put("StopReason",4);
                }else{
                    map1.put("StopReason",0);
                }
            }else{
                map1.put("StopReason",0);
            }
            map1.put("SumPeriod",xhpcHistoryOrder.getXhpcStatisticsTimeIntervalList().size());

            map.put("orderMassage",map1);

            List<Map<String, Object>> rateTimeList = xhpcHistoryOrderMapper.getRateTimeList(xhpcHistoryOrder.getRateModelId());

            map.put("rateTimeList",rateTimeList);

            return AjaxResult.success(map);
        }


        return AjaxResult.error("订单号为null,请重新输入");
    } @Override
    public AjaxResult addOrderMassageOrRateTime(String serialNumber,String chargeOrderInfo) {
        XhpcHistoryOrder xhpcHistoryOrder = xhpcHistoryOrderMapper.getOrderMassageOrRateTime(serialNumber);
        //ChargeOrderInfo orderInfo = JSON.parseObject(chargeOrderInfo, ChargeOrderInfo.class);

        redisService.setCacheObject("notification:"+xhpcHistoryOrder.getSerialNumber(),chargeOrderInfo);
        return AjaxResult.success("订单补退已提交，等待推送");
    }




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

        BigDecimal powerPriceTotal = new BigDecimal(0);
        BigDecimal servicePriceTotal = new BigDecimal(0);
        BigDecimal divide = new BigDecimal(totalPower);
        //累计充电时间、计费模型、开始时间、结束时间、已充金额
        XhpcChargeOrder chargeOrder = xhpcChargeOrderService.getSerialNumberMessage(serialNumber);
        Long rateModelId = chargeOrder.getRateModelId();
        Date startTime2 = chargeOrder.getStartTime();
        Date updateTime2 = chargeOrder.getEndTime();
        //充电度数
        BigDecimal chargingDegree = new BigDecimal(totalPower);
        List<Map<String, Object>> list = new ArrayList<>();
        //1时间没有跨天
        DateTime parse = DateUtil.parse(DateUtil.format(startTime2, "yyyy-MM-dd"), "yyyy-MM-dd");
        DateTime parse1 = DateUtil.parse(DateUtil.format(updateTime2, "yyyy-MM-dd"), "yyyy-MM-dd");
        long betweenDay = DateUtil.between(parse, parse1, DateUnit.DAY);

        if (betweenDay == 0) {
            return getBigDecimal(totalPrice, powerPriceTotal, servicePriceTotal, chargeOrder, rateModelId, startTime2, updateTime2, chargingDegree, list);
        } else {
            //当天晚上时间  23:59:59
            Map<String, Object> map =new HashMap<>();
            Date updateTime = DateUtil.endOfDay(startTime2);
            String format = DateUtil.format(updateTime, "yyyy-MM-dd HH:mm:ss");
            DateTime tomorrow = DateUtil.offsetDay(startTime2, 1);
            Date startTime3 = DateUtil.beginOfDay(tomorrow);
            Map<String, Object> twentyFour = xhpcHistoryOrderMapper.getXhpcRealTimeOrderTwentyFour(chargeOrder.getChargeOrderId(), format);

            if(twentyFour==null){
                return getBigDecimal(totalPrice, powerPriceTotal, servicePriceTotal, chargeOrder, rateModelId, startTime2, updateTime2, chargingDegree, list);
            }

            if(twentyFour !=null && twentyFour.get("chargingDegree")!=null){
                BigDecimal chargingDegree1 = new BigDecimal(twentyFour.get("chargingDegree").toString());
                BigDecimal decimal = divide.subtract(chargingDegree1);
                if(chargingDegree1.compareTo(new BigDecimal(0))==0){
                    String start = DateUtil.formatTime(updateTime);
                    Map<String, Object> map1 = new HashMap<>();
                    map1.put("time", start+"-23:59:59");
                    map1.put("powerPrice", 0);
                    map1.put("servicePrice", 0);
                    map1.put("chargingDegree", 0);
                    map1.put("actPrice", 0);
                    list.add(map1);
                    map.put("list", list);//数据列表
                    map.putAll(getBigDecimal(totalPrice, powerPriceTotal, servicePriceTotal, chargeOrder, rateModelId, startTime3, updateTime2, chargingDegree, list));
                    return map;
                }else if(decimal.compareTo(new BigDecimal(0))==1){
                    map =getBigDecimal(totalPrice, powerPriceTotal, servicePriceTotal, chargeOrder, rateModelId, startTime2, updateTime, chargingDegree1, list);
                    map.putAll(getBigDecimal(totalPrice, powerPriceTotal, servicePriceTotal, chargeOrder, rateModelId, startTime3, updateTime2, decimal, list));;
                    return map;
                }else{
                    String end = DateUtil.formatTime(updateTime2);
                    map.putAll(getBigDecimal(totalPrice, powerPriceTotal, servicePriceTotal, chargeOrder, rateModelId, startTime2, updateTime, chargingDegree, list));
                    Map<String, Object> map1 = new HashMap<>();
                    map1.put("time", "00:00:00-"+end);
                    map1.put("powerPrice", 0);
                    map1.put("servicePrice", 0);
                    map1.put("chargingDegree", 0);
                    map1.put("actPrice", 0);
                    list.add(map1);
                    map.put("list", list);//
                    return map;
                }
            }
            return null;
        }
    }


    private Map<String, Object> getBigDecimal(String totalPrice, 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<>();
        if(chargingDegree==null || chargingDegree.compareTo(new BigDecimal(0))==0){
            Map<String, Object> map1 = new HashMap<>();
            map1.put("time", 0);
            map1.put("powerPrice", totalPrice);
            map1.put("servicePrice", 0);
            map1.put("chargingDegree", chargeOrder.getChargingDegree());
            map1.put("actPrice", totalPrice);
            list.add(map1);
           // map.put("powerPriceTotal", 0);
           // map.put("servicePriceTotal", 0);
            map.put("list", list);//数据列表
            return map;
        }

        //算出相差时间,分
        BigDecimal decimal = new BigDecimal((updateTime2.getTime() - startTime2.getTime()) / 60000).setScale(2);

        if(decimal.compareTo(new BigDecimal(0))==0){
            Map<String, Object> map1 = new HashMap<>();
            map1.put("time", 0);
            map1.put("powerPrice", totalPrice);
            map1.put("servicePrice", 0);
            map1.put("chargingDegree", chargeOrder.getChargingDegree());
            map1.put("actPrice", totalPrice);
            list.add(map1);
            map.put("list", list);//数据列表
          //  map.put("powerPriceTotal", 0);
          //  map.put("servicePriceTotal", 0);
            return map;
        }
        //每分钟多少度
        BigDecimal degree = chargingDegree.divide(decimal, 3, BigDecimal.ROUND_HALF_UP);

        //获取费率时间段
        String startTime = DateUtil.formatTime(startTime2);
        String endTime = DateUtil.formatTime(updateTime2);
        if("00:00:00".equals(endTime)){
            endTime="23:59:59";
        }
        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(4, BigDecimal.ROUND_HALF_UP);
                //powerPriceTotal = powerFee.multiply(degree).setScale(2, BigDecimal.ROUND_HALF_UP);
                BigDecimal servicePrice = new BigDecimal(reatTimeList.get(0).get("serviceFee").toString()).setScale(4, BigDecimal.ROUND_HALF_UP);
                //servicePriceTotal=servicePrice.multiply(chargingDegree).setScale(2, BigDecimal.ROUND_HALF_UP);
                map1.put("time", startTime + "-" + endTime);
                map1.put("powerPrice", powerFee);
                map1.put("servicePrice", servicePrice);
                map1.put("chargingDegree", chargeOrder.getChargingDegree());
                map1.put("actPrice", totalPrice);
                list.add(map1);
                powerPriceTotal =powerPriceTotal.add(powerFee.multiply(degree).setScale(4, BigDecimal.ROUND_HALF_UP));
                servicePriceTotal =servicePriceTotal.add(servicePrice.multiply(chargingDegree).setScale(4, BigDecimal.ROUND_HALF_UP));
            } 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(4, BigDecimal.ROUND_HALF_UP);
                    BigDecimal servicePrice = new BigDecimal(objectMap.get("serviceFee").toString()).setScale(4, BigDecimal.ROUND_HALF_UP);
                    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("powerPriceTotal", powerPriceTotal);
      //  map.put("servicePriceTotal", servicePriceTotal);
        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(4, BigDecimal.ROUND_HALF_UP);
        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_HALF_UP);
        BigDecimal powerPriceTotal = new BigDecimal(0);
        //获取费率时间段
        String startTime = DateUtil.formatTime(startTime2);
        String endTime = DateUtil.formatTime(updateTime2);
        if("00:00:00".equals(endTime)){
            endTime="23:59:59";
        }
        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_HALF_UP));
            } 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 getBigDecimal(Long rateModelId, String startTime, String updateTime, BigDecimal powerPriceTotal, BigDecimal divide) {
        if("00:00:00".equals(updateTime)){
            updateTime="23:59:59";
        }
        List<Map<String, Object>> reatTimeList = getReatTimeList(startTime,updateTime, rateModelId);
        for (int i = 0; i <reatTimeList.size() ; i++) {
            int size = reatTimeList.size();
            Map<String, Object> map = reatTimeList.get(i);
            String startTime1 = map.get("startTime").toString();
            String endTime1 = map.get("endTime").toString();
            BigDecimal powerFee =new BigDecimal(map.get("powerFee").toString());
            if("00:00:00".equals(endTime1)){
                endTime1="23:59:59";
            }
            //获取费率
            if(size==1){
                powerPriceTotal = powerPriceTotal.add(getRateTimeList(startTime,updateTime,divide,powerFee));
            }else{
                if(i==0){
                    powerPriceTotal = powerPriceTotal.add(getRateTimeList(startTime,endTime1,divide,powerFee));
                } else if(i<size-1){
                    powerPriceTotal = powerPriceTotal.add(getRateTimeList(startTime1,endTime1,divide,powerFee));
                }else{
                    powerPriceTotal = powerPriceTotal.add(getRateTimeList(startTime1,updateTime,divide,powerFee));
                }
            }
        }
        return powerPriceTotal;
    }

    private  BigDecimal getRateTimeList(String startTime, String endTime, BigDecimal degree, BigDecimal powerPrice) {
        long time = DateUtil.parse(endTime).getTime();
        long time1= DateUtil.parse(startTime).getTime();
        BigDecimal multiply = new BigDecimal(time-time1).divide(new BigDecimal(60000),4, BigDecimal.ROUND_HALF_UP).multiply(degree).setScale(4,BigDecimal.ROUND_HALF_UP);
        BigDecimal bigDecimal = multiply.multiply(powerPrice).setScale(4, BigDecimal.ROUND_HALF_UP);
        return  bigDecimal;
    }

    private String translate(String stopReason) {

        String sr = SM.get(stopReason);
        if (sr == null) {
            final Integer stopReasonInt = Integer.valueOf(stopReason, 16);
            if (stopReasonInt <= 0x49) {
//            if (stopReasonInt >= 0x40 && stopReasonInt <= 0x49) { // todo wi lh 0x40?
                sr = "充电完成(0X".concat(stopReason).concat(")");
            } else if (stopReasonInt <= 0x69) {
                sr = "充电启动失败(0X".concat(stopReason).concat(")");
            } else if (stopReasonInt < 0x90) {
                sr = "充电异常中止(0X".concat(stopReason).concat(")");
            } else if (stopReasonInt == 0x90) {
                sr = "未知原因中止(0X".concat(stopReason).concat(")");
            } else {
                sr = "未知原因中止(UC_0X".concat(stopReason).concat(")");
            }
        }
        return sr;
//        }
    }

    public static final String date2String(Date date) {

        return date2String(date, "yyyyMMddHHmmss");
    }

    public static final String date2String(Date date, String format) {

        if (date == null) {
            return "";
        }
        DateFormat df = new SimpleDateFormat(format);
        return df.format(date);
    }

    public static void main(String[] args) {
        String num1 ="notification:80836000050009012605202331599222";
        System.out.println("==="+num1.substring(13));
        String num2 ="MA25CNM38260520233149738745";
        System.out.println("==="+num2.substring(0, 9));
    }

}
