package com.xhpc.order.api;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.xhpc.common.api.*;
import com.xhpc.common.api.dto.ChargingStationDto;
import com.xhpc.common.core.domain.R;
import com.xhpc.common.core.web.controller.BaseController;
import com.xhpc.common.data.redis.CacheBmsReqChargerOutputData;
import com.xhpc.common.data.redis.CacheOrderData;
import com.xhpc.common.data.redis.CacheRealtimeData;
import com.xhpc.common.domain.XhpcRate;
import com.xhpc.common.redis.service.RedisService;
import com.xhpc.common.util.UserTypeUtil;
import com.xhpc.order.config.ChargingCheckConfig;
import com.xhpc.order.domain.XhpcChargeOrder;
import com.xhpc.order.domain.XhpcHistoryOrder;
import com.xhpc.order.service.IXhpcChargeOrderService;
import com.xhpc.order.service.IXhpcHistoryOrderService;
import com.xhpc.order.service.IXhpcRealTimeOrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static cn.hutool.core.date.DateUnit.*;
import static com.xhpc.common.data.redis.StaticBeanUtil.REDIS;

@RestController
public class XhpcPileOrderController extends BaseController {

    @Autowired
    private RedisService redisService;

    @Autowired
    private IXhpcChargeOrderService xhpcChargeOrderService;

    @Autowired
    private IXhpcRealTimeOrderService xhpcRealTimeOrderService;

    @Autowired
    private WebSocketService webSocketService;

    @Autowired
    private IXhpcHistoryOrderService xhpcHistoryOrderService;

    @Autowired
    private UserTypeService userTypeService;

    @Autowired
    private WorkOrderYuService workOrderYuService;

    @Autowired
    private PowerPileService powerPileService;

    @Autowired
    private EvcsService evcsService;

    @Autowired
    private ChargingCheckConfig chargingCheckConfig;

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

    // 缓存key常量
    private static final String CACHE_KEY_CHECK_THRESHOLD = "charging:check:threshold";
    /**
     * 桩启动回调接口
     *
     * @param orderNo 订单号
     * @param status  1 成功 2失败
     * @param remark  备注
     * @return
     */
    @GetMapping("/chargeOrder/pileStartup")
    public R pileStartup(@RequestParam(value = "orderNo")String orderNo, @RequestParam(value = "status")Integer status,@RequestParam(value = "remark") String remark) {
        logger.info("桩启动回调接口>>>>>状态："+status+"备注++"+remark+"订单号"+orderNo);
        XhpcHistoryOrder historyOrder = xhpcHistoryOrderService.getHistoryOrderById(null, orderNo);
        //解析订单编号
        Long userId =0L;
        Integer code =200;
        XhpcChargeOrder xhpcChargeOrder = xhpcChargeOrderService.getSerialNumberMessage(orderNo);
        if(xhpcChargeOrder==null|| xhpcChargeOrder.getUserId()==null){
            logger.info("桩启动回调接口--无效订单号>>>>>orderNo：" + orderNo);
            return R.fail(500,"无效订单号");
        }

        if(historyOrder !=null){
            logger.info(">>>>>订单已结算不在改变订单状态>>>>>>>>>");
            return R.ok();
        }

        if(xhpcChargeOrder.getRateModelId()==null){
            ChargingStationDto chargingStationDto = REDIS.getCacheObject("station:" + xhpcChargeOrder.getChargingStationId());
            if(chargingStationDto.getRateModelId() !=null){
                xhpcChargeOrder.setRateModelId(chargingStationDto.getRateModelId());
                xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
            }
        }



        if (status == 1) {
            userId = update(0, remark, orderNo, 0);
        } else {
            code = 500;
            userId = update(-1,  remark, orderNo, 0);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("code", code);
        map.put("userId", userId);
        map.put("message", remark);
        JSONObject json = new JSONObject(map);
        logger.info("桩启动回调接口>>>>>json："+json.toString());
        Integer source = xhpcChargeOrder.getSource();
        String tenantId = xhpcChargeOrder.getTenantId();
        String message = "";
        if(UserTypeUtil.USER_TYPE.equals(source)){
            message = tenantId + UserTypeUtil.USER + userId;
        }else if(UserTypeUtil.COMMUNIT_TYPE.equals(source)){
            message = tenantId + UserTypeUtil.COMMUNIT + userId;
        }else if(UserTypeUtil.CUSTOMERS_TYPE.equals(source)){
            message = tenantId + UserTypeUtil.CUSTOMERS + userId;
        }else if(UserTypeUtil.INTERNET_TYPE.equals(source) && userId>10000){
            message = tenantId + UserTypeUtil.CYCUSER + userId;
            if(code==200){
                Map<String, Object> map1 = new HashMap<>();
                map1.put("OperatorID", "MA6CC2LK7");
                map1.put("orderNo", orderNo);
                logger.info(">>>启动回调>>川逸充启动结果推送接口>>>>>>>>>");
                evcsService.getCYCNotificationStartChargeResult(map1);
                logger.info(">>>启动回调>>川逸充启动结果推送接口>>>>>>>>>");
            }
        }
        //消息对了内容
        if(xhpcChargeOrder.getSource()==UserTypeUtil.USER_TYPE){
            webSocketService.getMessage(message,json.toString());
        }
        return R.ok();
    }

    /**
     * 桩停止回调接口
     *
     * @param orderNo 订单号
     * @param status  1 成功 2失败 3数据中断 4恢复数据
     * @param remark  备注
     * @return
     */
    @GetMapping("/chargeOrder/pileStop")
    public R pileStop(@RequestParam(value = "orderNo")String orderNo, @RequestParam(value = "status")Integer status,@RequestParam(value = "remark") String remark) {
        logger.info("桩停止回调接口>>>>>状态："+status+"备注++"+remark+"订单号"+orderNo);

        if("".equals(orderNo) || orderNo==null){
            logger.info(">>>>>桩停止回调接口--订单号为空>>>>>>>>>");
            return R.ok();
        }
        XhpcHistoryOrder historyOrder = xhpcHistoryOrderService.getHistoryOrderById(null, orderNo);
        //解析订单编号
        if(historyOrder !=null){
            logger.info(">>>>>订单已结算不在改变订单状态>>>>>>>>>");
            return R.ok();
        }
        //解析订单编号
        Integer code = 500;
        Long userId=0L;
        Map<String, Object> map = new HashMap<>();
        XhpcChargeOrder xhpcChargeOrder = xhpcChargeOrderService.getSerialNumberMessage(orderNo);
        if(xhpcChargeOrder==null|| xhpcChargeOrder.getUserId()==null){
            logger.info("桩停止回调接口--无效订单号>>>>>orderNo：" + orderNo);
            return R.fail(500,"无效订单号");
        }
        if(status == 1|| status == 2){
            userId = update(0,  remark, orderNo, 1);
            map.put("userId", userId);
        }
        if (status == 1) {
            xhpcChargeOrder.setStatus(0);
            map.put("message", "停止充电成功");
        } else if(status==2){
            //停止充电失败
            code=300;
            map.put("message", remark);
        }else if(status==3 || status==4){
            //订单定位异常,修改充电订单状态
            if(status==3) {
                xhpcChargeOrder.setErroRemark(remark);
                xhpcChargeOrder.setStatus(2);
                xhpcChargeOrder.setUpdateTime(new Date());
                //获取实时订单
                Map<String, Object> cacheMap = redisService.getCacheMap("order:" + orderNo);
                List<CacheRealtimeData> list = (List<CacheRealtimeData>) cacheMap.get("realtimeDataList");
                if (list != null && list.size() > 0) {
                    int number = 0;
                    if (list.size() != 1) {
                        number = list.size() - 1;
                    }
                    BigDecimal decimal = new BigDecimal(10000);
                    CacheRealtimeData cacheRealtimeData = list.get(number);
                    xhpcChargeOrder.setChargingDegree(new BigDecimal(cacheRealtimeData.getChargingDegree()).divide(decimal));
                    //充电时长
                    Long tiem = Long.valueOf(cacheRealtimeData.getChargingTime() / 1000);
                    if (tiem > 3600) {
                        long hours = tiem / 3600;
                        double mins = (double) ((tiem - (hours * 3600)) / 60);
                        xhpcChargeOrder.setChargingTime(hours + "时" + new BigDecimal(mins).setScale(0) + "分");
                    } else {
                        double mins = (double) (tiem / 60);
                        xhpcChargeOrder.setChargingTime(new BigDecimal(mins).setScale(0) + "分");
                    }
                    xhpcChargeOrder.setChargingTimeNumber(Long.valueOf(cacheRealtimeData.getChargingTime()));
                    xhpcChargeOrder.setAmountCharged(new BigDecimal(cacheRealtimeData.getAmountCharged()).divide(decimal));
                    xhpcChargeOrder.setEndSoc(""+cacheRealtimeData.getSoc());

                    CacheRealtimeData cacheRealtimeData1 = list.get(0);
                    xhpcChargeOrder.setStartSoc(""+cacheRealtimeData1.getSoc());
                }
            }else{
                if (xhpcChargeOrder.getStatus() == 1 || xhpcChargeOrder.getStatus() == 3) {
                    //不修改订单
                } else {
                    xhpcChargeOrder.setStatus(0);
                }
            }
            xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
            code = 300;
            userId =xhpcChargeOrder.getUserId();
            map.put("userId",userId);
            map.put("message", remark);
        }else{
            //修改订单，判断订单
        }
        Integer source = xhpcChargeOrder.getSource();
        String tenantId = xhpcChargeOrder.getTenantId();
        String message = "";
        if(UserTypeUtil.USER_TYPE.equals(source)){
            message = tenantId + UserTypeUtil.USER + userId;
        }else if(UserTypeUtil.COMMUNIT_TYPE.equals(source)){
            message = tenantId + UserTypeUtil.COMMUNIT + userId;
        }else if(UserTypeUtil.CUSTOMERS_TYPE.equals(source)){
            message = tenantId + UserTypeUtil.CUSTOMERS + userId;
        }else if(UserTypeUtil.INTERNET_TYPE.equals(source) && userId>10000){
            message = tenantId + UserTypeUtil.CYCUSER + userId;
        }
        if(xhpcChargeOrder.getSource()==UserTypeUtil.USER_TYPE || (UserTypeUtil.INTERNET_TYPE.equals(source) && userId>10000)){
            map.put("code", code);
            JSONObject json = new JSONObject(map);
            //消息对了内容
            webSocketService.getMessage(message,json.toString());
        }
        return R.ok();
    }

    /**
     * 桩实时数据回调接口
     * @param orderNo   订单号
     * @return
     */
    @Transactional
    @GetMapping("/chargeOrder/pileRimeOrder")
    public R pileRealtime(@RequestParam(value = "orderNo")String orderNo) {

        logger.info("桩实时数据回调接口>>>>>orderNo：" + orderNo);


        //获取实时订单
        CacheRealtimeData cacheRealtimeData = redisService.getCacheObject("order:" + orderNo + ".lord");

        XhpcChargeOrder xhpcChargeOrder = xhpcChargeOrderService.getSerialNumberMessage(orderNo);

        if(xhpcChargeOrder==null|| xhpcChargeOrder.getUserId()==null){
            logger.info("桩实时数据回调接口--无效订单号>>>>>orderNo：" + orderNo);
            return R.fail(500,"无效订单号");
        }

        if(xhpcChargeOrder.getStatus()==null){
            xhpcChargeOrder.setStatus(0);
            if(xhpcChargeOrder.getInternetSerialNumber()!=null && xhpcChargeOrder.getSource()==null){
                xhpcChargeOrder.setSource(1);
            }
        }

        if(xhpcChargeOrder.getStatus()==1||xhpcChargeOrder.getStatus()==2||xhpcChargeOrder.getStatus()==3){
            XhpcHistoryOrder historyOrder = xhpcHistoryOrderService.getHistoryOrderById(null, orderNo);
            if(historyOrder!=null){
                logger.info("桩实时数据回调接口--重复订单号>>>>>orderNo：" + orderNo);
                return R.fail(500,"无效订单号");
            }
        }

        Map<String, Object> cacheMap = redisService.getCacheMap("order:"+orderNo);
        if(cacheMap==null || cacheMap.get("startType")==null ){
            logger.info("桩实时数据回调接口--无效订单号>>>>>orderNo：" + orderNo);
            return R.fail(500,"无效订单号");
        }
        if("01".equals(cacheMap.get("startType").toString())){
            if(!"刷卡".equals(xhpcChargeOrder.getChargingMode())){
                logger.info("桩实时数据回调接口--无效订单号>>>>>orderNo：" + orderNo);
                return R.fail(500,"无效订单号");
            }
        }
        if("03".equals(cacheMap.get("startType").toString())){
            if(!"VIN码".equals(xhpcChargeOrder.getChargingMode())){
                logger.info("桩实时数据回调接口--无效订单号>>>>>orderNo：" + orderNo);
                return R.fail(500,"无效订单号");
            }
        }

        String key = "pile:"+orderNo.substring(0,14);
        Map<String, Object> cachePile = REDIS.getCacheMap(key);
        if(cacheRealtimeData !=null &&cachePile !=null && cachePile.get("equipmentType") !=null && "1".equals(cachePile.get("equipmentType").toString()) ){

            String keys = "RealtimeOrder:"+orderNo;
            Map<String, Object> keysMap = new HashMap<>();
            Map<String, Object> keysMapOrder = redisService.getCacheMap(keys);
            int number =1;


            if(keysMapOrder !=null && keysMapOrder.get("number") !=null){
                number =(Integer)keysMapOrder.get("number");
                if(number<9 && (keysMapOrder.get("identical") ==null || "".equals(keysMapOrder.get("identical").toString()))){
                    keysMapOrder.put("identical","0");
                }else{
                    if(keysMapOrder.get("identical") ==null || "".equals(keysMapOrder.get("identical").toString())){
                        keysMapOrder.put("identical","0");
                    }
                }
                Integer soc = cacheRealtimeData.getSoc();

                if(number%3==1){
                    if(cacheRealtimeData.getAmountCharged() !=null){
                        keysMap.put("amountCharged1",cacheRealtimeData.getAmountCharged());
                    }
                    if(cacheRealtimeData.getChargingDegree() !=null){
                        keysMap.put("chargingDegree1",cacheRealtimeData.getChargingDegree());
                    }
                }else if(number%3==2){
                    if(cacheRealtimeData.getAmountCharged() !=null){
                        keysMap.put("amountCharged2",cacheRealtimeData.getAmountCharged());
                    }
                    if(cacheRealtimeData.getChargingDegree() !=null){
                        keysMap.put("chargingDegree2",cacheRealtimeData.getChargingDegree());
                    }
                }else{
                    if(cacheRealtimeData.getAmountCharged() !=null){
                        keysMap.put("amountCharged3",cacheRealtimeData.getAmountCharged());
                    }
                    if(cacheRealtimeData.getChargingDegree() !=null){
                        keysMap.put("chargingDegree3",cacheRealtimeData.getChargingDegree());
                    }
                }
                // ========== 使用当前阈值（程序启动时已从缓存加载或使用配置文件） ==========
                int numberThreshold = chargingCheckConfig.getNumberThreshold();
                int socThreshold = chargingCheckConfig.getSocThreshold();
                int orderPowerThreshold = chargingCheckConfig.getOrderPower();  // 获取电量阈值
                int orderVoltageThreshold = chargingCheckConfig.getVoltageThreshold();  // 获取电压
                int orderCurrentThreshold = chargingCheckConfig.getCurrentThreshold();  // 获取电流
                if(number >= numberThreshold){
                    String chargingDegree ="";
                    String amountCharged ="";
                    if(number%3==1){
                        chargingDegree =keysMapOrder.get("chargingDegree1").toString();
                        amountCharged =keysMapOrder.get("amountCharged1").toString();
                    }else if(number%3==2){
                        chargingDegree =keysMapOrder.get("chargingDegree2").toString();
                        amountCharged =keysMapOrder.get("amountCharged2").toString();
                    }else{
                        chargingDegree =keysMapOrder.get("chargingDegree3").toString();
                        amountCharged =keysMapOrder.get("amountCharged3").toString();
                    }
                    String identical =keysMapOrder.get("identical").toString();
                    String substring = orderNo.substring(0, 14);
                    // 标记本次是否有异常
                    boolean hasError = false;
                    String errorMsg = null;
                    // 1. SOC过低校验（需要额外判断SOC条件）
                    if(soc < socThreshold){
                        if(chargingDegree.equals(cacheRealtimeData.getChargingDegree().toString()) ||amountCharged.equals(cacheRealtimeData.getAmountCharged().toString())){
                            hasError = true;
                            errorMsg = "充电桩校验故障(数据不一致)";
                        }
                        // 电压校验
                        int workingVoltage = cacheRealtimeData.getWorkingVoltage();
                        if(workingVoltage < orderVoltageThreshold){
                            hasError = true;
                            errorMsg = "电压小于"+orderVoltageThreshold+"V，停止充电";
                        }

//                        Integer workingCurrent = cacheRealtimeData.getWorkingCurrent();
//
//                        if(workingCurrent < orderCurrentThreshold){
//                            hasError = true;
//                            errorMsg = "电流小于"+orderCurrentThreshold+"A，停止充电";
//                        }
                    }
                    // 2. 电量增量校验（所有达到阈值的订单都执行）
                    if(!hasError){
                        if(chargingDegree.equals(cacheRealtimeData.getChargingDegree().toString()) ||(cacheRealtimeData.getChargingDegree() - Integer.valueOf(chargingDegree) <= orderPowerThreshold)){
                            hasError = true;
                            errorMsg = "充电桩电量增长异常";
                        }
                    }
                    // 统一处理 identical 计数
                    if(hasError){
                        int currentIdentical = Integer.parseInt(identical);
                        currentIdentical++;  // 异常次数+1
                        if(currentIdentical > 2){  // 大于2次，停止充电
                            xhpcChargeOrder.setRemark(errorMsg);
                            xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
                            powerPileService.stopCharging(orderNo, substring, orderNo.substring(0, 16), "0C");
                            logger.info("充电异常停止，订单号：{}，异常次数：{}，原因：{}", orderNo, currentIdentical, errorMsg);
                            return R.fail(500, errorMsg);
                        } else {
                            // 记录异常次数，继续充电
                            keysMap.put("identical", String.valueOf(currentIdentical));
                            logger.info("充电异常警告，订单号：{}，异常次数：{}，原因：{}", orderNo, currentIdentical, errorMsg);
                        }
                    } else {
                        // 正常情况，重置计数
                        keysMap.put("identical", "0");
                    }

                }else{
                    keysMap.put("identical","0");
                }
                number++;
            }

            keysMap.put("orderNo",cacheRealtimeData.getOrderNo());
            keysMap.put("number",number);
            keysMap.put("createTime",cacheRealtimeData.getCreateTime());
            if(cacheRealtimeData.getWorkingVoltage() !=null){
                keysMap.put("workingVoltage",cacheRealtimeData.getWorkingVoltage());
            }
            if(cacheRealtimeData.getWorkingVoltage() !=null){
                keysMap.put("workingCurrent",cacheRealtimeData.getWorkingCurrent());
            }


            redisService.setCacheMap(keys,keysMap);
        }


        Long userId = xhpcChargeOrder.getUserId();
        Integer source = xhpcChargeOrder.getSource();
        String tenantId = xhpcChargeOrder.getTenantId();

        if(xhpcChargeOrder.getMark() !=null && xhpcChargeOrder.getMotorcadeType()==1 && cacheRealtimeData !=null){
            Long motorcadeId = xhpcChargeOrder.getMotorcadeId();
            // 1. 存储当前订单金额到Redis
            String orderKey = xhpcChargeOrder.getMark()+":"+motorcadeId+":"+xhpcChargeOrder.getSerialNumber();
            redisService.setCacheObject(orderKey,cacheRealtimeData.getAmountCharged());

            // 2. 查询当前所有充电订单
            Collection<String> keys = redisService.keys(xhpcChargeOrder.getMark()+":"+motorcadeId+":*");
            System.out.println("=====================查询当前所有充电订单=============================="+keys.size());
            if(keys.size()>1){
                int ruleCents = getRuleCents(keys.size());
                //获取总金额
                String totalKey =xhpcChargeOrder.getMark()+":"+motorcadeId;
                BigDecimal totalMoney = (BigDecimal)redisService.getCacheObject(totalKey);
                String substring = orderNo.substring(0, 14);
                // 计算实时总金额（元）
                BigDecimal realtimeTotal = BigDecimal.ZERO;
                for (String okey : keys) {
                    Object amountObj = redisService.getCacheObject(okey);
                    if (amountObj != null) {
                        // 金额需要除以10000转为元
                        BigDecimal amountInCents = new BigDecimal(amountObj.toString());
                        BigDecimal amountInYuan = amountInCents.divide(new BigDecimal(10000), 2, RoundingMode.HALF_UP);
                        realtimeTotal = realtimeTotal.add(amountInYuan);
                    }
                }
                System.out.println("=====================计算实时总金额=============================="+realtimeTotal.toString());
                if(totalMoney.subtract(realtimeTotal).compareTo(new BigDecimal(ruleCents))<=0){
                    //停止充电
                    xhpcChargeOrder.setRemark("车队金额大于设置值");
                    xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
                    powerPileService.stopCharging(orderNo, substring,orderNo.substring(0, 16), "0C");
                    System.out.println("=====================p平台下发停止充电=============================="+xhpcChargeOrder.getSerialNumber());
                    return R.fail(500,"充电桩校验故障");
                }

            }
        }
        try {
            Date date = new Date();
            xhpcChargeOrder.setEndTime(date);
            xhpcChargeOrder.setUpdateTime(date);
            xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
            if(cacheRealtimeData !=null){
                Map<String, Object> map = xhpcRealTimeOrderService.addOrderTime(cacheRealtimeData, xhpcChargeOrder, orderNo, 1);

                if(!UserTypeUtil.INTERNET_TYPE.equals(source) ||(UserTypeUtil.INTERNET_TYPE.equals(source) && userId>10000)){
                    //存入换成
                    JSONObject json = new JSONObject(map);
                    String message = "";
                    if(UserTypeUtil.USER_TYPE.equals(source)){
                        message = tenantId + UserTypeUtil.USER + userId;
                    }else if(UserTypeUtil.COMMUNIT_TYPE.equals(source)){
                        message = tenantId + "ST" + userId;
                    }else if(UserTypeUtil.CUSTOMERS_TYPE.equals(source)){
                        message = tenantId + "BE" + userId;
                    }else if(UserTypeUtil.INTERNET_TYPE.equals(source) && userId>10000){
                        message = tenantId + UserTypeUtil.CYCUSER + userId;
                    }else if(UserTypeUtil.MOTORCADE_TYPE.equals(source)){
                        message = tenantId + "Z" + userId;
                    }else if(UserTypeUtil.MOTORCADE_USER_TYPE.equals(source)){
                        message = tenantId + "D" + userId;
                    }
                    redisService.setCacheMap("realTimeTenantId:"+message,map);
                    webSocketService.getMessage(message,json.toString());
                    //消息对了内容
                    logger.info("桩实时数据发送WebSocket成功>>>>>orderNo：" + orderNo+"websocket :"+message);
                }
            }
        } catch (Exception e) {
            Map<String, Object> map = new HashMap<>();
            map.put("code", 500);
            map.put("userId", xhpcChargeOrder.getUserId());
            JSONObject json = new JSONObject(map);
            String message = "";
            if(UserTypeUtil.USER_TYPE.equals(source)){
                message = tenantId + UserTypeUtil.USER + userId;
            }else if(UserTypeUtil.COMMUNIT_TYPE.equals(source)){
                message = tenantId + "ST" + userId;
            }else if(UserTypeUtil.CUSTOMERS_TYPE.equals(source)){
                message = tenantId + "BE"  + userId;
            }else if(UserTypeUtil.INTERNET_TYPE.equals(source) && userId>10000){
                message = tenantId + UserTypeUtil.CYCUSER + userId;
            }else if(UserTypeUtil.MOTORCADE_TYPE.equals(source)){
                message = tenantId + "Z"  + userId;
            }else if(UserTypeUtil.MOTORCADE_USER_TYPE.equals(source)){
                message = tenantId + "D"  + userId;
            }
            if(xhpcChargeOrder.getSource()==UserTypeUtil.USER_TYPE){
                //消息对了内容
                webSocketService.getMessage(message,json.toString());
            }
            return R.fail(500,"无实时数据");
        }
        return R.ok();
    }


    /**
     * 桩订单结束回调
     */
    @Transactional
    @GetMapping(value = "/chargeOrder/pileEndOrder")
    public R pileEndOrder(@RequestParam(value = "orderNo") String orderNo) {
        logger.info("桩订单结束回调>>>>>orderNo："+orderNo);
        try{
            if("".equals(orderNo) || orderNo==null){
                logger.info(">>>>>桩停止回调接口--订单号为空>>>>>>>>>");
                return R.ok();
            }
            XhpcHistoryOrder historyOrder = xhpcHistoryOrderService.getHistoryOrderById(null, orderNo);
            if(historyOrder !=null){
                logger.info("订单已结束不能重复结算>>>>>orderNo："+orderNo);
                return R.ok();
            }
            //获取实时订单
            Map<String, Object> cacheMap = redisService.getCacheMap("order:"+orderNo);
            if(cacheMap==null || cacheMap.get("orderData")==null ){
                logger.info("无效订单号>>>>>orderNo：" + orderNo);
                return R.fail(500,"无效订单号："+orderNo);
            }
            if("00000000000000000000000000000000".equals(orderNo)){
                logger.info("无效订单号>>>>>orderNo：" + orderNo);
                return R.ok();
            }
            //获取充电订单
            XhpcChargeOrder xhpcChargeOrder = xhpcChargeOrderService.getSerialNumberMessage(orderNo);
            Integer source = xhpcChargeOrder.getSource();
            String tenantId = xhpcChargeOrder.getTenantId();
            //历史订单
            Long userId = xhpcChargeOrder.getUserId();
            Map<String, Object> pushOrder = redisService.getCacheMap("pushOrder:"+orderNo);
            //判断结算订单是否有回复启动成功
            boolean judge =false;
            if(pushOrder !=null){
                if(pushOrder.get("startChargeSeqStat") ==null){
                    judge =true;
                }else if("2".equals(pushOrder.get("startChargeSeqStat").toString())){
                    //正常结算
                }else{
                    judge=true;
                }
            }else{
                judge =true;
            }
            if (judge) {
                CacheOrderData cacheOrderData = (CacheOrderData)cacheMap.get("orderData");
                if(cacheOrderData==null || cacheOrderData.getTotalPowerQuantity()==0){
                    xhpcChargeOrder.setStatus(3);
                    xhpcChargeOrder.setUpdateTime(new Date());
                    xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
                    xhpcRealTimeOrderService.addZeroHistoryOrder(xhpcChargeOrder);
                }else{
                    xhpcChargeOrder.setStatus(2);
                    xhpcChargeOrder.setUpdateTime(new Date());
                    xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
                }
                logger.info("*********************订单号>>>>>orderNo：" + orderNo);
                logger.info("*********************订单号>>>>>orderNo：" + orderNo);
                return R.ok();
            }

            CacheOrderData cacheOrderData = (CacheOrderData)cacheMap.get("orderData");
            //停止原因
            try{
                if(cacheOrderData.getStopReason() !=null && !"".equals(cacheOrderData.getStopReason())){
                    xhpcChargeOrder.setType(cacheOrderData.getStopReason());
                }else{
                    if(cacheMap.get("stopReasonHex")!=null){
                        xhpcChargeOrder.setType(cacheMap.get("stopReasonHex").toString());
                    }else{
                        xhpcChargeOrder.setType("199");
                    }
                }
            }catch (Exception e){}
            if(xhpcChargeOrder == null ){
                logger.info("无效订单号>>>>>orderNo：" + orderNo);
                return R.fail(500,"无效订单号："+orderNo);
            }
            BigDecimal bigDecimal = new BigDecimal(10000);
            BigDecimal totalPowerQuantity = new BigDecimal(cacheOrderData.getTotalPowerQuantity()).divide(bigDecimal,4,BigDecimal.ROUND_HALF_UP);
            if(totalPowerQuantity.compareTo(new BigDecimal(500)) > -1){
                logger.info("结算电量大于500度>>"+totalPowerQuantity+">>>orderNo：" + orderNo);
                xhpcChargeOrder.setStatus(2);
                xhpcChargeOrder.setChargingDegree(totalPowerQuantity);
                xhpcChargeOrder.setUpdateTime(new Date());
                xhpcChargeOrder.setErroRemark("结算电量大于500度");
                xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
                return R.fail(500,"无效订单号："+orderNo);
            }
            DateTime startTime = DateUtil.parse(cacheOrderData.getStartTime());
            DateTime endTime = DateUtil.parse(cacheOrderData.getEndTime());
            xhpcChargeOrder.setStartTime(startTime);
            xhpcChargeOrder.setEndTime(endTime);
            //开始时间不能小于今天2天  结束时间不能大于今天两天
            Date dateUtil = DateUtil.date();
            long betweenStart = DateUtil.between(startTime, dateUtil, DateUnit.DAY);
            if(betweenStart>2){
                logger.info("开始时间大于本地时间2天>>>>>orderNo：" + orderNo);
                xhpcChargeOrder.setStatus(2);
                xhpcChargeOrder.setUpdateTime(new Date());
                xhpcChargeOrder.setErroRemark("开始时间大于本地时间2天,需要进行时间效验");
                xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
                extracted();
                return R.fail(500,"无效订单号："+orderNo);
            }
            if(endTime.getTime()-dateUtil.getTime()>120000){
                logger.info("结束时间大于本地时间2分钟,需要进行时间效验>>>>>orderNo：" + orderNo);
                xhpcChargeOrder.setStatus(2);
                xhpcChargeOrder.setUpdateTime(new Date());
                xhpcChargeOrder.setErroRemark("结束时间大于本地时间2分钟,需要进行时间效验");
                xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
                extracted();
                return R.fail(500,"无效订单号："+orderNo);
            }
            //结束时间小于开始时间
            if(startTime.getTime()-endTime.getTime()>0){
                logger.info("开始时间大于结束时间>>>>>orderNo：" + orderNo);
                xhpcChargeOrder.setStatus(2);
                xhpcChargeOrder.setUpdateTime(new Date());
                xhpcChargeOrder.setErroRemark("开始时间大于结束时间,需要进行时间效验");
                xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
                return R.fail(500,"无效订单号："+orderNo);
            }

            //1.订单结束时上报的开始时间小于订单创建时间3分钟 2.订单结束时上报的开始时间大于订单创建时间5分钟
            long createTimeLong = xhpcChargeOrder.getCreateTime().getTime();

            if(cacheOrderData.getStartTime() !=null || "".equals(cacheOrderData.getStartTime())){
                long startTimeLong = DateUtil.parse(cacheOrderData.getStartTime()).getTime();
                if(createTimeLong-startTimeLong>120000){
                    if("15".equals(xhpcChargeOrder.getChargingStationId().toString())){
                        xhpcChargeOrder.setStartTime(xhpcChargeOrder.getCreateTime());
                        xhpcChargeOrder.setErroRemark("结算订单开始充电时间小于订单创建时间2分钟");
                    }else{
                      xhpcChargeOrder.setStatus(2);
                      xhpcChargeOrder.setChargingDegree(totalPowerQuantity);
                      xhpcChargeOrder.setUpdateTime(new Date());
                      xhpcChargeOrder.setErroRemark("结算订单开始充电时间小于订单创建时间2分钟");
                      xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
                      return R.fail(500,"无效订单号："+orderNo);
                    }
                }
                if(startTimeLong-createTimeLong>180000){
                    if("15".equals(xhpcChargeOrder.getChargingStationId().toString())){
                        xhpcChargeOrder.setStartTime(xhpcChargeOrder.getCreateTime());
                        xhpcChargeOrder.setErroRemark("结算订单开始充电时间大于订单创建时间3分钟");
                    }else{
                      xhpcChargeOrder.setStatus(2);
                    xhpcChargeOrder.setChargingDegree(totalPowerQuantity);
                    xhpcChargeOrder.setUpdateTime(new Date());
                    xhpcChargeOrder.setErroRemark("结算订单开始充电时间大于订单创建时间3分钟");
                    xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
                    return R.fail(500,"无效订单号："+orderNo);
                    }
                }
            }else{
                xhpcChargeOrder.setStatus(2);
                xhpcChargeOrder.setChargingDegree(totalPowerQuantity);
                xhpcChargeOrder.setUpdateTime(new Date());
                xhpcChargeOrder.setErroRemark("结算订单开始充电时间为空");
                xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
                return R.fail(500,"无效订单号："+orderNo);
            }

            BigDecimal money = new BigDecimal(cacheOrderData.getCost()).divide(bigDecimal,2,BigDecimal.ROUND_HALF_UP);

            if(cacheOrderData.getTotalPowerQuantity()==0 || totalPowerQuantity.compareTo(new BigDecimal(0.1))<1 || money.compareTo(new BigDecimal(0.1))<1){


                xhpcChargeOrder.setStatus(3);
                xhpcChargeOrder.setUpdateTime(new Date());
                int startSoc1 = cacheOrderData.getStartSoc();
                int endSoc1 = cacheOrderData.getEndSoc();

                xhpcChargeOrder.setStartSoc(startSoc1 + "");
                xhpcChargeOrder.setEndSoc(endSoc1 + "");
                Date date = new Date();
                BigDecimal bigDecimal1 = new BigDecimal(0);
                xhpcChargeOrder.setStartTime(date);
                xhpcChargeOrder.setEndTime(date);
                xhpcChargeOrder.setChargingTime("0分");
                xhpcChargeOrder.setChargingDegree(bigDecimal1);
                try{
                    if(cacheOrderData.getStopReason() !=null && !"".equals(cacheOrderData.getStopReason())){
                        xhpcChargeOrder.setType(cacheOrderData.getStopReason());
                    }else{
                        if(cacheMap.get("stopReasonHex")!=null){
                            xhpcChargeOrder.setType(cacheMap.get("stopReasonHex").toString());
                        }else{
                            xhpcChargeOrder.setType("199");
                        }
                    }
                }catch (Exception e){}
                xhpcChargeOrder.setAmountCharged(bigDecimal1);
                xhpcChargeOrder.setChargingTimeNumber(0L);
                xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
                //xhpcRealTimeOrderService.addZeroHistoryOrder(xhpcChargeOrder);
                logger.info("*********************电量为0订单号>>>>>orderNo：" + orderNo);
                logger.info("*********************电量为0订单号>>>>>orderNo：" + orderNo);
                //生成一条历史订单
                XhpcHistoryOrder xhpcHistoryOrder = new XhpcHistoryOrder();
                xhpcHistoryOrder.setStartTime(date);
                xhpcHistoryOrder.setClearingType(xhpcChargeOrder.getClearingType());
                xhpcHistoryOrder.setInternetSerialNumber(xhpcChargeOrder.getInternetSerialNumber());
                xhpcHistoryOrder.setEndTime(date);
                xhpcHistoryOrder.setPowerPriceTotal(bigDecimal1);
                xhpcHistoryOrder.setServicePriceTotal(bigDecimal1);
                xhpcHistoryOrder.setTotalPower(0.0);
                xhpcHistoryOrder.setMeterValueStartEvcs(cacheOrderData.getElectricMeterStart().doubleValue());
                xhpcHistoryOrder.setMeterValueEndEvcs(cacheOrderData.getElectricMeterEnd().doubleValue());
                xhpcHistoryOrder.setVinNormal(xhpcChargeOrder.getVinNormal());
                xhpcHistoryOrder.setType(1);
                xhpcHistoryOrder.setUserNameEvcs(xhpcChargeOrder.getDriverId());
                xhpcHistoryOrder.setPhone(xhpcChargeOrder.getDriverId());
                xhpcHistoryOrder.setUserNameEvcs(xhpcChargeOrder.getDriverId());
                Map<String, Object> userMessage =new HashMap<>();

                if(!UserTypeUtil.INTERNET_TYPE.equals(source)||(UserTypeUtil.INTERNET_TYPE.equals(source) && userId>1000)){
                    R user = userTypeService.getUser(null, userId, source, null, tenantId);
                    if(user !=null && user.getData() !=null ){
                        userMessage = (Map<String, Object>)user.getData();
                        if (userMessage == null || userMessage.get("balance") == null) {
                            logger.info("获取用户信息失败>>userMessage>>>orderNo："+orderNo);
                            return R.fail(500,"添加订单回调失败");
                        }
                    }else{
                        logger.info("获取用户信息失败>>user>>>orderNo："+orderNo);
                        return R.fail(500,"添加订单回调失败");
                    }
                }else{
                    if(pushOrder !=null){
                        if(pushOrder.get("internetSerialNumber") !=null){
                            xhpcHistoryOrder.setInternetSerialNumber(pushOrder.get("internetSerialNumber").toString());
                        }
                        if(pushOrder.get("operatorId3rdpty") !=null){
                            xhpcHistoryOrder.setOperatorId3rdptyEvcs((String) pushOrder.get("operatorId3rdpty"));
                        }
                    }
                }
                xhpcRealTimeOrderService.addSettlement(bigDecimal1,bigDecimal1,bigDecimal1,bigDecimal1,bigDecimal1,xhpcChargeOrder,userId,userMessage,1,cacheOrderData.getVinNormal(),xhpcHistoryOrder);

                Map<String, Object> map = new HashMap<>();
                map.put("code", 500);
                map.put("userId", userId);
                map.put("type", 2);
                map.put("chargingOrderId", xhpcChargeOrder.getChargeOrderId());
                JSONObject json = new JSONObject(map);

                if(!UserTypeUtil.INTERNET_TYPE.equals(source) && (UserTypeUtil.INTERNET_TYPE.equals(source) && userId>10000)){
                    String message ="";
                    if(UserTypeUtil.USER_TYPE.equals(source)){
                        message=tenantId+UserTypeUtil.USER+userId;
                    }else if(UserTypeUtil.COMMUNIT_TYPE.equals(source)){
                        message=tenantId+UserTypeUtil.COMMUNIT+userId;
                    }else if(UserTypeUtil.CUSTOMERS_TYPE.equals(source)){
                        message = tenantId + UserTypeUtil.CUSTOMERS + userId;
                    }else if(UserTypeUtil.INTERNET_TYPE.equals(source) && userId>10000){
                        message = tenantId + UserTypeUtil.CYCUSER + userId;
                    }
                    webSocketService.getMessage(message,json.toString());
                }
                return R.ok();
            }
            if(xhpcChargeOrder.getStatus()==1 || xhpcChargeOrder.getStatus()==3){
                logger.info("订单已结束不能重复结算>>>>>orderNo："+orderNo+">>>chargeOrderId:"+xhpcChargeOrder.getChargeOrderId());
                return R.ok();
            }
            //解析订单编号
            Date date = new Date();
            //总金额


            //00: 尖费率 01: 峰费率 02: 平费率 03: 谷费率
            BigDecimal t1powerFee =new BigDecimal(0);
            BigDecimal t2powerFee =new BigDecimal(0);
            BigDecimal t3powerFee =new BigDecimal(0);
            BigDecimal t4powerFee =new BigDecimal(0);
            BigDecimal t1serviceFee =new BigDecimal(0);
            BigDecimal t2serviceFee =new BigDecimal(0);
            BigDecimal t3serviceFee =new BigDecimal(0);
            BigDecimal t4serviceFee =new BigDecimal(0);
            //费率计费模型
            List<XhpcRate> rateModelList = xhpcChargeOrderService.getRateModelId(xhpcChargeOrder.getRateModelId());
            logger.info("&&&&&&&&&&&&&&&&&&&&&&&&&&&&订单号："+xhpcChargeOrder.getSerialNumber()+"&&&&&&&&&&&&&&费率模型id："+xhpcChargeOrder.getRateModelId());

            for (XhpcRate xhpcRate:rateModelList) {
                if(UserTypeUtil.MOTORCADE_TYPE==xhpcChargeOrder.getSource() ||UserTypeUtil.MOTORCADE_USER_TYPE==xhpcChargeOrder.getSource()){

                    if(xhpcChargeOrder.getMark()==null){
                        xhpcChargeOrder.setStatus(2);
                        xhpcChargeOrder.setChargingDegree(totalPowerQuantity);
                        xhpcChargeOrder.setUpdateTime(new Date());
                        xhpcChargeOrder.setErroRemark("车队结算时，车队标识不存在");
                        xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
                        return R.fail(500,"无效订单号："+orderNo);
                    }

                    R motorcadeMap = userTypeService.getOrderMotorcade(xhpcChargeOrder.getMark());
                    if(motorcadeMap !=null && motorcadeMap.getData() !=null ){
                        Map<String, Object> motorcadeMessage = (Map<String, Object>)motorcadeMap.getData();
                        if (motorcadeMessage == null) {
                            logger.info("获取用户信息失败>>userMessage>>>orderNo："+orderNo);
                            return R.fail(500,"添加订单回调失败");
                        }

                        if("00".equals(xhpcRate.getRateValue())){
                            t1powerFee = new BigDecimal(String.valueOf(motorcadeMessage.get("peakSharpElectricity")));
                            t1serviceFee =new BigDecimal(String.valueOf(motorcadeMessage.get("peakSharpService")));
                        }
                        if("01".equals(xhpcRate.getRateValue())){
                            t2powerFee = new BigDecimal(String.valueOf(motorcadeMessage.get("peakElectricity")));
                            t2serviceFee =new BigDecimal(String.valueOf(motorcadeMessage.get("peakService")));
                        }
                        if("02".equals(xhpcRate.getRateValue())){
                            t3powerFee = new BigDecimal(String.valueOf(motorcadeMessage.get("flatElectricity")));
                            t3serviceFee = new BigDecimal(String.valueOf(motorcadeMessage.get("flatService")));
                        }
                        if("03".equals(xhpcRate.getRateValue())){
                            t4powerFee =new BigDecimal(String.valueOf(motorcadeMessage.get("valleyElectricity")));
                            t4serviceFee =new BigDecimal(String.valueOf(motorcadeMessage.get("valleyService")));
                        }
                    }else{
                        logger.info("获取用户信息失败>>user>>>orderNo："+orderNo);
                        return R.fail(500,"添加订单回调失败");
                    }


                }else{
                    if("00".equals(xhpcRate.getRateValue())){
                        t1powerFee = xhpcRate.getPowerFee();
                        t1serviceFee =xhpcRate.getServiceFee();
                    }
                    if("01".equals(xhpcRate.getRateValue())){
                        t2powerFee = xhpcRate.getPowerFee();
                        t2serviceFee =xhpcRate.getServiceFee();
                    }
                    if("02".equals(xhpcRate.getRateValue())){
                        t3powerFee = xhpcRate.getPowerFee();
                        t3serviceFee = xhpcRate.getServiceFee();
                    }
                    if("03".equals(xhpcRate.getRateValue())){
                        t4powerFee = xhpcRate.getPowerFee();
                        t4serviceFee =xhpcRate.getServiceFee();
                    }
                }
            }
            //总电费
            BigDecimal powerPrice =new BigDecimal(0);
            Integer totalPower =0;
            BigDecimal servicePrice =new BigDecimal(0);
            //因桩有误差，电费和服务费重新计算
            if(!"0".equals(cacheOrderData.getT1PowerQuantity().toString())){
                totalPower =totalPower+cacheOrderData.getT1PowerQuantity();
                BigDecimal multiply1 = new BigDecimal(cacheOrderData.getT1PowerQuantity()).divide(bigDecimal).multiply(t1powerFee).setScale(4, BigDecimal.ROUND_HALF_UP);
                BigDecimal multiply2 = new BigDecimal(cacheOrderData.getT1PowerQuantity()).divide(bigDecimal).multiply(t1serviceFee).setScale(4, BigDecimal.ROUND_HALF_UP);
                powerPrice=powerPrice.add(multiply1);
                servicePrice=servicePrice.add(multiply2);
            }
            if(!"0".equals(cacheOrderData.getT2PowerQuantity().toString())){
                totalPower =totalPower+cacheOrderData.getT2PowerQuantity();
                BigDecimal multiply1 = new BigDecimal(cacheOrderData.getT2PowerQuantity()).divide(bigDecimal).multiply(t2powerFee).setScale(4, BigDecimal.ROUND_HALF_UP);
                BigDecimal multiply2 = new BigDecimal(cacheOrderData.getT2PowerQuantity()).divide(bigDecimal).multiply(t2serviceFee).setScale(4, BigDecimal.ROUND_HALF_UP);
                powerPrice=powerPrice.add(multiply1);
                servicePrice=servicePrice.add(multiply2);
            }
            if(!"0".equals(cacheOrderData.getT3PowerQuantity().toString())){
                totalPower =totalPower+cacheOrderData.getT3PowerQuantity();
                BigDecimal multiply1 = new BigDecimal(cacheOrderData.getT3PowerQuantity()).divide(bigDecimal).multiply(t3powerFee).setScale(4, BigDecimal.ROUND_HALF_UP);
                BigDecimal multiply2 = new BigDecimal(cacheOrderData.getT3PowerQuantity()).divide(bigDecimal).multiply(t3serviceFee).setScale(4, BigDecimal.ROUND_HALF_UP);
                powerPrice=powerPrice.add(multiply1);
                servicePrice=servicePrice.add(multiply2);
            }
            if(!"0".equals(cacheOrderData.getT4PowerQuantity().toString())){
                totalPower =totalPower+cacheOrderData.getT4PowerQuantity();
                BigDecimal multiply1 = new BigDecimal(cacheOrderData.getT4PowerQuantity()).divide(bigDecimal).multiply(t4powerFee).setScale(4, BigDecimal.ROUND_HALF_UP);
                BigDecimal multiply2 = new BigDecimal(cacheOrderData.getT4PowerQuantity()).divide(bigDecimal).multiply(t4serviceFee).setScale(4, BigDecimal.ROUND_HALF_UP);
                powerPrice=powerPrice.add(multiply1);
                servicePrice=servicePrice.add(multiply2);
            }
            powerPrice =powerPrice.setScale(2,BigDecimal.ROUND_HALF_UP);
            //总服务费
            servicePrice =servicePrice.setScale(2,BigDecimal.ROUND_HALF_UP);
            if(UserTypeUtil.MOTORCADE_TYPE==xhpcChargeOrder.getSource()||UserTypeUtil.MOTORCADE_USER_TYPE==xhpcChargeOrder.getSource()){
                money= powerPrice.add(servicePrice);
            }else{
                //防止出现负数
                if(powerPrice.add(servicePrice).compareTo(money)==-1){
                    if(powerPrice.compareTo(money)==1){
                        powerPrice =money;
                        servicePrice = money.subtract(powerPrice);
                    }else{
                        servicePrice = money.subtract(powerPrice);
                    }
                }else{
                    money = powerPrice.add(servicePrice);
                }
            }

            if(money.compareTo(new BigDecimal(1000)) > -1){
                logger.info("结算金额大于1000>>"+money+">>>orderNo：" + orderNo);
                xhpcChargeOrder.setStatus(2);
                xhpcChargeOrder.setUpdateTime(new Date());
                xhpcChargeOrder.setErroRemark("充电金额大于1000元");
                xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
                return R.fail(500,"无效订单号："+orderNo);
            }

            //剩余的电费
            BigDecimal surplusPowerPrice = powerPrice;
            //剩余的服务费
            BigDecimal surplusServicePrice = servicePrice;
            int startSoc = cacheOrderData.getStartSoc();
            int endSoc = cacheOrderData.getEndSoc();

            xhpcChargeOrder.setStartSoc(startSoc + "");
            xhpcChargeOrder.setEndSoc(endSoc + "");
            int status = cacheOrderData.getStatus();
            xhpcChargeOrder.setStatus(status);

            //充电时长
            Long tiem = (endTime.getTime() - startTime.getTime()) / 1000;
            if (tiem > 3600) {
                long hours = tiem / 3600;
                double mins = (double) ((tiem - (hours * 3600)) / 60);
                xhpcChargeOrder.setChargingTime(hours + "时" + new BigDecimal(mins).setScale(0) + "分");
            } else {
                double mins = (double) (tiem / 60);
                xhpcChargeOrder.setChargingTime(new BigDecimal(mins).setScale(0) + "分");
            }
            if(!"".equals(cacheOrderData.getVinNormal())||cacheOrderData.getVinNormal() !=null){
                xhpcChargeOrder.setVinNormal(cacheOrderData.getVinNormal());
            }
            xhpcChargeOrder.setChargingTimeNumber(tiem);
            BigDecimal divide = new BigDecimal(cacheOrderData.getTotalPowerQuantity()).divide(bigDecimal,4, BigDecimal.ROUND_HALF_UP);
            xhpcChargeOrder.setChargingDegree(divide);
            xhpcChargeOrder.setAmountCharged(money);
            String stopReason = cacheOrderData.getStopReason();
            if("充电桩校验故障".equals(xhpcChargeOrder.getRemark())){

            }else{
                xhpcChargeOrder.setRemark(stopReason);
            }
            xhpcChargeOrder.setUpdateTime(date);
            xhpcChargeOrder.setStatus(status);
            //生成一条历史订单
            XhpcHistoryOrder xhpcHistoryOrder = new XhpcHistoryOrder();
            xhpcHistoryOrder.setClearingType(xhpcChargeOrder.getClearingType());
            xhpcHistoryOrder.setStartTime(startTime);
            xhpcHistoryOrder.setEndTime(endTime);
            xhpcHistoryOrder.setPowerPriceTotal(powerPrice);
            xhpcHistoryOrder.setServicePriceTotal(servicePrice);
            xhpcHistoryOrder.setTotalPower(totalPower.doubleValue()/10000);
            xhpcHistoryOrder.setMeterValueStartEvcs(cacheOrderData.getElectricMeterStart().doubleValue());
            xhpcHistoryOrder.setMeterValueEndEvcs(cacheOrderData.getElectricMeterEnd().doubleValue());
            xhpcHistoryOrder.setVinNormal(xhpcChargeOrder.getVinNormal());
            Map<String, Object> userMessage =new HashMap<>();

            if(!UserTypeUtil.INTERNET_TYPE.equals(source)||(UserTypeUtil.INTERNET_TYPE.equals(source) && userId>1000)){
                R user = userTypeService.getUser(null, userId, source, null, tenantId);
                if(user !=null && user.getData() !=null ){
                    userMessage = (Map<String, Object>)user.getData();
                    if (userMessage == null || userMessage.get("balance") == null) {
                        logger.info("获取用户信息失败>>userMessage>>>orderNo："+orderNo);
                        return R.fail(500,"添加订单回调失败");
                    }
                }else{
                    logger.info("获取用户信息失败>>user>>>orderNo："+orderNo);
                    return R.fail(500,"添加订单回调失败");
                }
            }else{
                if(pushOrder !=null){
                    if(pushOrder.get("internetSerialNumber") !=null){
                        xhpcHistoryOrder.setInternetSerialNumber(pushOrder.get("internetSerialNumber").toString());
                    }
                    if(pushOrder.get("operatorId3rdpty") !=null){
                        xhpcHistoryOrder.setOperatorId3rdptyEvcs((String) pushOrder.get("operatorId3rdpty"));
                    }
                }
            }

            xhpcHistoryOrder.setType(1);
            xhpcHistoryOrder.setPhone(xhpcChargeOrder.getDriverId());
            xhpcHistoryOrder.setUserNameEvcs(xhpcChargeOrder.getDriverId());
            //结算
            R r = xhpcRealTimeOrderService.addSettlement(powerPrice,servicePrice,money,surplusPowerPrice,surplusServicePrice,xhpcChargeOrder,userId,userMessage,1,cacheOrderData.getVinNormal(),xhpcHistoryOrder);
            if(r.getCode()==200){
                Map<String, Object> map = new HashMap<>();
                map.put("code", 500);
                map.put("userId", userId);
                map.put("type", 2);
                map.put("chargingOrderId", xhpcChargeOrder.getChargeOrderId());
                JSONObject json = new JSONObject(map);

                if(!UserTypeUtil.INTERNET_TYPE.equals(source)){
                    String message ="";
                    if(UserTypeUtil.USER_TYPE.equals(source)){
                        message=tenantId+UserTypeUtil.USER+userId;
                    }else if(UserTypeUtil.COMMUNIT_TYPE.equals(source)){
                        message=tenantId+UserTypeUtil.COMMUNIT+userId;
                    }else if(UserTypeUtil.CUSTOMERS_TYPE.equals(source)){
                        message = tenantId + UserTypeUtil.CUSTOMERS + userId;
                    }else if(UserTypeUtil.INTERNET_TYPE.equals(source) && userId>10000){
                        message = tenantId + UserTypeUtil.CYCUSER + userId;
                    }else if(UserTypeUtil.MOTORCADE_TYPE.equals(source)){
                        message = tenantId + UserTypeUtil.MOTORCADE_PERSON_IN_CHARGE + userId;
                    }else if(UserTypeUtil.MOTORCADE_USER_TYPE.equals(source)){
                        message = tenantId + UserTypeUtil.MOTORCADE_USER + userId;
                    }
                    webSocketService.getMessage(message,json.toString());
                }
            }else{
                Map<String, Object> map = new HashMap<>();
                map.put("code", 300);
                map.put("userId", userId);
                map.put("type", 2);
                map.put("chargingOrderId", xhpcChargeOrder.getChargeOrderId());
                map.put("msg", "请重新点击停止充电");
                JSONObject json = new JSONObject(map);

                if(!UserTypeUtil.INTERNET_TYPE.equals(source)){
                    String message ="";
                    if(UserTypeUtil.USER_TYPE.equals(source)){
                        message=tenantId+UserTypeUtil.USER+userId;
                    }else if(UserTypeUtil.COMMUNIT_TYPE.equals(source)){
                        message=tenantId+UserTypeUtil.COMMUNIT+userId;
                    }else if(UserTypeUtil.CUSTOMERS_TYPE.equals(source)){
                        message = tenantId + UserTypeUtil.CUSTOMERS + userId;
                    }else if(UserTypeUtil.INTERNET_TYPE.equals(source) && userId>10000){
                        message = tenantId + UserTypeUtil.CYCUSER + userId;
                    }
                    webSocketService.getMessage(message,json.toString());
                }
                return R.fail();
            }
        }catch (Exception e){
            e.printStackTrace();
            logger.info("添加订单回调失败>>>>>orderNo："+orderNo);
            return R.fail(500,"添加订单回调失败");
        }
        String keys = "RealtimeOrder:"+orderNo;
        redisService.deleteObject(keys);

        return R.ok();
    }




    /**
     * 订单异常回调接口
     */
    @Transactional
    @PostMapping("/chargeOrder/abnormalOrder")
    public R abnormalOrder(@RequestParam(value = "orderNo") String orderNo) {
        //获取实时订单
       XhpcChargeOrder xhpcChargeOrder = xhpcChargeOrderService.getSerialNumberMessage(orderNo);
        if(xhpcChargeOrder==null|| xhpcChargeOrder.getUserId()==null){
            logger.info("订单异常回调接口--无效订单号>>>>>orderNo：" + orderNo);
            return R.fail(500,"无效订单号");
        }
        XhpcHistoryOrder historyOrder = xhpcHistoryOrderService.getHistoryOrderById(null, orderNo);
        if(historyOrder !=null){
            logger.info("订单已结束不能重复结算>>>>>orderNo："+orderNo);
            return R.ok();
        }
        if(xhpcChargeOrder.getStatus()==1 || xhpcChargeOrder.getStatus()==3){
            logger.info("订单异常回调接口--已结算订单>>>>>orderNo：" + orderNo);
            return R.ok();
        }
        Integer source = xhpcChargeOrder.getSource();
        String tenantId = xhpcChargeOrder.getTenantId();
//        if(!UserTypeUtil.INTERNET_TYPE.equals(source)){
//            R user = userTypeService.getUser(null, xhpcChargeOrder.getUserId(), source, null, tenantId);
//            if(user !=null && user.getData() !=null){
//                Map<String, Object> userMessage = (Map<String, Object>)user.getData();
//                if (userMessage != null && userMessage.get("balance") != null) {
//                    xhpcHistoryOrderService.addXhpcChargeOrder(userMessage,orderNo,1);
//                }
//            }
//        }else{
//            xhpcHistoryOrderService.addXhpcChargeOrder(null,orderNo,1);
//        }
        //双枪修改逻辑，查询是否是双枪
        if(xhpcChargeOrder.getSunchaStatus()!=0){
            String userType =UserTypeUtil.USER;
            if(UserTypeUtil.COMMUNIT_TYPE==xhpcChargeOrder.getSource()){
                userType =UserTypeUtil.COMMUNIT;
            }else if(UserTypeUtil.CUSTOMERS_TYPE==xhpcChargeOrder.getSource()){
                userType =UserTypeUtil.CUSTOMERS;
            }
            Map<String, Object> map = new HashMap<>();
            if(xhpcChargeOrder.getSunchaStatus()==1){
                map.put("aBalanceStatus",2);
            }else{
                map.put("bBalanceStatus",2);
            }
            String key = "user:" + xhpcChargeOrder.getUserId() + userType + ".order";
            redisService.setCacheMap(key,map);
        }
        Date date = new Date();
        xhpcChargeOrder.setStatus(2);
        xhpcChargeOrder.setEndTime(date);
        xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);

        Long userId = xhpcChargeOrder.getUserId();
        Map<String, Object> map = new HashMap<>();
        map.put("code", 500);
        map.put("userId", xhpcChargeOrder.getUserId());
        JSONObject json = new JSONObject(map);
        if(!UserTypeUtil.INTERNET_TYPE.equals(source)){
            String message ="";
            if(UserTypeUtil.USER_TYPE.equals(source)){
                message=tenantId+UserTypeUtil.USER+userId;
            }else if(UserTypeUtil.COMMUNIT_TYPE.equals(source)){
                message=tenantId+UserTypeUtil.COMMUNIT+userId;
            }else if(UserTypeUtil.CUSTOMERS_TYPE.equals(source)){
                message = tenantId + UserTypeUtil.CUSTOMERS + userId;
            }else if(UserTypeUtil.INTERNET_TYPE.equals(source) && userId>10000){
                message = tenantId + UserTypeUtil.CYCUSER + userId;
            }
            webSocketService.getMessage(message,json.toString());
        }
        logger.info("异常桩实时数据发送WebSocket成功>>>>>orderNo：" + orderNo);
        return R.ok();
    }

    /**
     * @param status       状态
     * @param remark       备注
     * @param serialNumber 订单号
     * @param type         结束订单状态
     * @return
     */
    private Long update(Integer status, String remark, String serialNumber, Integer type) {
        logger.info("状态："+status+"备注++"+remark+"订单号"+serialNumber);
        XhpcChargeOrder xhpcChargeOrder = xhpcChargeOrderService.getSerialNumberMessage(serialNumber);
        Date date = new Date();
        if(status==0){
            xhpcChargeOrder.setStatus(0);
            xhpcChargeOrder.setStartTime(date);
            //查询是否是双枪
            if(xhpcChargeOrder.getSunchaStatus()!=0){
                String userType =UserTypeUtil.USER;
                if(UserTypeUtil.COMMUNIT_TYPE==xhpcChargeOrder.getSource()){
                    userType =UserTypeUtil.COMMUNIT;
                }else if(UserTypeUtil.CUSTOMERS_TYPE==xhpcChargeOrder.getSource()){
                    userType =UserTypeUtil.CUSTOMERS;
                }

                Map<String, Object> map = new HashMap<>();
                if(xhpcChargeOrder.getSunchaStatus()==1){
                    map.put("aBalanceStatus",0);
                }else{
                    map.put("bBalanceStatus",0);
                }
                String key = "user:" + xhpcChargeOrder.getUserId() + userType + ".order";
                redisService.setCacheMap(key,map);
            }
        } else{
            xhpcChargeOrder.setStatus(-1);
            xhpcChargeOrder.setDelFlag(1);
            xhpcChargeOrder.setEndTime(date);
        }
        //xhpcChargeOrder.setErroRemark(remark);

        Long userId = xhpcChargeOrder.getUserId();
        if (type == 1) {
            //充电订单  --结束soc、充电时长、充电度数
            xhpcChargeOrder.setEndTime(date);
        }
        xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);

        return userId;
    }


@GetMapping(value = "/chargeOrder/pileStartUpBy3rd")
public R pileStartUpBy3rd(@RequestParam(value = "internetSerialNumber") String internetSerialNumber,
                          @RequestParam(value = "driverId", required = false) String driverId,
                          @RequestParam(value = "chargingAmt", required = false, defaultValue = "500") Integer chargingAmt,
                          @RequestParam(value = "plateNum", required = false) String plateNum,
                          @RequestParam(value = "status") Integer status,
                          @RequestParam(value = "connectorId") String connectorId) {

    logger.info("<<<<<<<<<<<<<<<<<<<<<<<<第三方启动>>>>>>>>>>>>>>>>>"+internetSerialNumber);
    logger.info("<<<<<<<<<<<<<<<<<<<<<<<<第三方启动>>>>>>>>>>>>>>>>>"+internetSerialNumber);
    return xhpcChargeOrderService.startUpBy3rd(internetSerialNumber, driverId, chargingAmt, plateNum, status, connectorId);
}



    private void extracted() {
        Date date = DateUtil.date();
        workOrderYuService.addNewOrder("28","有异常订单订单且该桩进行校时效价处理","定时任务自动扫描异常订单","","","","");
    }

    /**
     * 桩实时数据BMS回调接口
     * @param orderNo   订单号
     * @return
     */
    @Transactional
    @GetMapping("/chargeOrder/pileRimeOrderBms")
    public R pileRimeOrderBms(@RequestParam(value = "orderNo")String orderNo) {

        logger.info("桩实时数据BMS回调接口>>>>>orderNo：" + orderNo);
        //获取实时订单
        xhpcRealTimeOrderService.addRealTimeOrderBms(orderNo);
        return R.ok();
    }


    @GetMapping("/chargeOrder/realtimeOrderDedis")
    public R realtimeOrderDedis() {
        logger.info("清除缓存>>>>>RealtimeOrder：");
        //获取实时订单
        Collection<String> realtimeOrder = REDIS.keys("RealtimeOrder:*");
        for (String okey : realtimeOrder) {
            redisService.deleteObject(okey);
        }
        return R.ok();
    }


    @GetMapping("/getUserMoney")
    public void getUserMoney(Integer number,String serialNumber,Integer source,Long userId ){
        if(number==9 || number==20){
            Map<String, Object> cacheMap = redisService.getCacheMap("order:"+serialNumber);
            //当number=9、20时，判断一次用户金额与当前下发余额是否相等，不相等停止充电
            if(!UserTypeUtil.INTERNET_TYPE.equals(source)){
                String keyUser =serialNumber+":"+userId;
                Object amountObj = redisService.getCacheObject(keyUser);
                boolean stop =true;
                if(amountObj !=null ){
                    BigDecimal balance1 =new BigDecimal(amountObj.toString());
                    if(cacheMap.get("initBalance") !=null){
                        BigDecimal bigDecimal = new BigDecimal(cacheMap.get("initBalance").toString()).divide(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_CEILING);
                        if(balance1.compareTo(bigDecimal)!=0){
                            stop =false;
                        }
                    }
                }else{
                    //停止充电
                }
                if(!stop){
                    System.out.println("=============获取用户金额失败====平台下发停止充电==========");
                }
            }
        }
    }

    /**
     * 更清晰的规则获取方法（使用Map）
     */
    private int getRuleCents(int vehicleCount) {
        // 使用Map更直观
        Map<Integer, Integer> rules = new HashMap<>();
        rules.put(1, 1);
        rules.put(2, 10);
        rules.put(3, 20);
        rules.put(4, 30);
        rules.put(5, 40);

        // 6辆及以上返回50
        if (vehicleCount >= 6) {
            return 50;
        }

        return rules.getOrDefault(vehicleCount, 0);
    }


    @PostMapping("/chargeOrder/updateCheckThreshold")
    public R updateCheckThreshold(@RequestParam(value = "numberThreshold", required = false) Integer numberThreshold,
                                  @RequestParam(value = "socThreshold", required = false) Integer socThreshold,
                                  @RequestParam(value = "orderPower", required = false) Integer orderPower,
                                  @RequestParam(value = "voltageThreshold", required = false) Integer voltageThreshold,
                                  @RequestParam(value = "currentThreshold", required = false) Integer currentThreshold) {
        logger.info("更新充电校验阈值>>>>>numberThreshold：{}，socThreshold：{}，orderPower：{}，voltageThreshold：{}，currentThreshold：{}",
                numberThreshold, socThreshold, orderPower, voltageThreshold, currentThreshold);

        try {
            if (numberThreshold != null && numberThreshold > 0) {
                chargingCheckConfig.setNumberThreshold(numberThreshold);
            }
            if (socThreshold != null && socThreshold > 0 && socThreshold <= 100) {
                chargingCheckConfig.setSocThreshold(socThreshold);
            }
            if (orderPower != null && orderPower > 0) {
                chargingCheckConfig.setOrderPower(orderPower);
            }
            // 新增：电压阈值
            if (voltageThreshold != null && voltageThreshold > 0) {
                chargingCheckConfig.setVoltageThreshold(voltageThreshold);
            }
            // 新增：电流阈值
            if (currentThreshold != null && currentThreshold > 0) {
                chargingCheckConfig.setCurrentThreshold(currentThreshold);
            }

            // 存入Redis缓存
            Map<String, Object> thresholdMap = new HashMap<>();
            thresholdMap.put("numberThreshold", chargingCheckConfig.getNumberThreshold());
            thresholdMap.put("socThreshold", chargingCheckConfig.getSocThreshold());
            thresholdMap.put("orderPower", chargingCheckConfig.getOrderPower());
            thresholdMap.put("voltageThreshold", chargingCheckConfig.getVoltageThreshold());
            thresholdMap.put("currentThreshold", chargingCheckConfig.getCurrentThreshold());
            thresholdMap.put("updateTime", new Date().toString());
            redisService.setCacheMap(CACHE_KEY_CHECK_THRESHOLD, thresholdMap);

            Map<String, Object> result = new HashMap<>();
            result.put("currentNumberThreshold", chargingCheckConfig.getNumberThreshold());
            result.put("currentSocThreshold", chargingCheckConfig.getSocThreshold());
            result.put("currentOrderPower", chargingCheckConfig.getOrderPower());
            result.put("currentVoltageThreshold", chargingCheckConfig.getVoltageThreshold());
            result.put("currentCurrentThreshold", chargingCheckConfig.getCurrentThreshold());
            result.put("message", "阈值更新成功并已存入缓存");

            return R.ok(result);
        } catch (Exception e) {
            logger.error("更新阈值失败", e);
            return R.fail(500, "更新阈值失败：" + e.getMessage());
        }
    }

    @GetMapping("/chargeOrder/getCheckThreshold")
    public R getCheckThreshold() {
        Map<String, Object> result = new HashMap<>();
        result.put("numberThreshold", chargingCheckConfig.getNumberThreshold());
        result.put("socThreshold", chargingCheckConfig.getSocThreshold());
        result.put("orderPower", chargingCheckConfig.getOrderPower());
        result.put("voltageThreshold", chargingCheckConfig.getVoltageThreshold());     // 新增
        result.put("currentThreshold", chargingCheckConfig.getCurrentThreshold());     // 新增
        result.put("defaultNumberThreshold", chargingCheckConfig.getDefaultNumberThreshold());
        result.put("defaultSocThreshold", chargingCheckConfig.getDefaultSocThreshold());
        result.put("defaultOrderPower", chargingCheckConfig.getDefaultOrderPower());
        result.put("defaultVoltageThreshold", chargingCheckConfig.getDefaultVoltageThreshold());  // 新增
        result.put("defaultCurrentThreshold", chargingCheckConfig.getDefaultCurrentThreshold());  // 新增
        result.put("cacheLoaded", chargingCheckConfig.isCacheLoaded());
        result.put("message", "获取成功");
        return R.ok(result);
    }

    @PostMapping("/chargeOrder/resetCheckThreshold")
    public R resetCheckThreshold() {
        logger.info("重置充电校验阈值为配置文件默认值");

        try {
            // 重置内存中的阈值（ChargingCheckConfig.resetToDefault() 已包含电压电流）
            chargingCheckConfig.resetToDefault();

            // 删除Redis缓存
            redisService.deleteObject(CACHE_KEY_CHECK_THRESHOLD);

            Map<String, Object> result = new HashMap<>();
            result.put("currentNumberThreshold", chargingCheckConfig.getNumberThreshold());
            result.put("currentSocThreshold", chargingCheckConfig.getSocThreshold());
            result.put("currentOrderPower", chargingCheckConfig.getOrderPower());
            result.put("currentVoltageThreshold", chargingCheckConfig.getVoltageThreshold());
            result.put("currentCurrentThreshold", chargingCheckConfig.getCurrentThreshold());
            result.put("message", "已重置为配置文件默认值并清除缓存");

            logger.info("阈值重置成功 - number阈值: {}, SOC阈值: {}, 电量阈值: {}, 电压阈值: {}, 电流阈值: {}",
                    chargingCheckConfig.getNumberThreshold(),
                    chargingCheckConfig.getSocThreshold(),
                    chargingCheckConfig.getOrderPower(),
                    chargingCheckConfig.getVoltageThreshold(),
                    chargingCheckConfig.getCurrentThreshold());

            return R.ok(result);
        } catch (Exception e) {
            logger.error("重置阈值失败", e);
            return R.fail(500, "重置阈值失败：" + e.getMessage());
        }
    }
}
