2021与蓝度共同重构项目,服务端
zhanzhiqin
2022-08-31 c121143d54615f71d0b87a88ab09da7cfd16d9e4
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/amqp/processor/c3ChargingProcessor.java
@@ -1,9 +1,7 @@
package com.sandu.ximon.admin.manager.iot.amqp.processor;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sandu.common.util.SpringContextHolder;
import com.sandu.ximon.admin.config.RedisConfig;
import com.sandu.ximon.admin.manager.iot.frame.inner.report.A5C3CommonReportInnerFrame;
import com.sandu.ximon.admin.manager.iot.frame.inner.report.A5C3ErrorCodeReportInnerFrame;
import com.sandu.ximon.admin.manager.iot.frame.inner.report.A5C3HeartbeatReportInnerFrame;
@@ -11,23 +9,16 @@
import com.sandu.ximon.admin.manager.iot.rrpc.dto.CommonFrame;
import com.sandu.ximon.admin.manager.iot.rrpc.enums.C3ChargingEnum;
import com.sandu.ximon.admin.manager.iot.rrpc.enums.C3mRedisConstant;
import com.sandu.ximon.admin.service.C3ChargingService;
import com.sandu.ximon.admin.service.C3mOrderService;
import com.sandu.ximon.admin.service.PoleBindingService;
import com.sandu.ximon.admin.service.PoleService;
import com.sandu.ximon.admin.service.*;
import com.sandu.ximon.admin.utils.LogUtils;
import com.sandu.ximon.admin.utils.RedisUtils;
import com.sandu.ximon.admin.vo.C3mOrderVO;
import com.sandu.ximon.dao.domain.C3mCharging;
import com.sandu.ximon.dao.domain.C3mOrder;
import com.sandu.ximon.dao.domain.Pole;
import com.sandu.ximon.dao.domain.PoleBinding;
import com.sandu.ximon.dao.enums.OrderStatus;
import com.sandu.ximon.dao.enums.OrderType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Date;
import java.math.BigDecimal;
/**
 * @author ZZQ
@@ -59,166 +50,111 @@
    @Override
    public void process(String productKey, String deviceName, CommonFrame frame) {
        String functionCode = frame.getPayload().substring(2, 4);
        if (C3ChargingEnum.NETWORK_REQUEST.getCode().equals(functionCode)) {
            A5C3CommonReportInnerFrame netRequestFrame = new A5C3CommonReportInnerFrame().transformFrame(frame.getPayload());
            log.info("C3充电桩上报处理_netRequestFrame");
            log.info(netRequestFrame.toString());
        //TODO
        if (frame.getPayload().contains("0000048E") || frame.getPayload().contains("FEA5820018F040001000000000")) {
            if (C3ChargingEnum.NETWORK_REQUEST.getCode().equals(functionCode)) {
                A5C3CommonReportInnerFrame netRequestFrame = new A5C3CommonReportInnerFrame().transformFrame(frame.getPayload());
                log.info("C3充电桩上报处理_netRequestFrame");
                log.info(netRequestFrame.toString());
            if (netRequestFrame.isValidate()) {
                //保存充电桩硬件信息
                boolean b = SpringContextHolder.getBean(C3ChargingService.class).saveReporEquipment(deviceName, netRequestFrame.getMcuUdid(), netRequestFrame.getDestinationAddress());
                //检查是否有正在进行的订单,有的话继续充电
                SpringContextHolder.getBean(C3mOrderService.class).recoverContinueCharing(netRequestFrame.getDestinationAddress(), netRequestFrame.getMcuUdid());
                if (!b) {
                    return;
                if (netRequestFrame.isValidate()) {
                    //保存充电桩硬件信息
                    SpringContextHolder.getBean(C3ChargingService.class)
                            .saveReporEquipment(deviceName, netRequestFrame.getMcuUdid(), netRequestFrame.getDestinationAddress());
                }
            }
        } else if (C3ChargingEnum.QR_CODE_REQUEST.getCode().equals(functionCode)) {
            //  网页操作二维码请求(41)
            A5C3CommonReportInnerFrame codeRequestFrame = new A5C3CommonReportInnerFrame().transformFrame(frame.getPayload());
            log.info("C3充电桩上报处理_codeRequestFrame");
            log.info(codeRequestFrame.toString());
            } else if (C3ChargingEnum.QR_CODE_REQUEST.getCode().equals(functionCode)) {
                //  网页操作二维码请求(41)
                A5C3CommonReportInnerFrame codeRequestFrame = new A5C3CommonReportInnerFrame().transformFrame(frame.getPayload());
                log.info("C3充电桩上报处理_codeRequestFrame");
                log.info(codeRequestFrame.toString());
            if (codeRequestFrame.isValidate()) {
                if (deviceName != null) {
                    //设置二维码
                    Pole pole = SpringContextHolder.getBean(PoleService.class).getOne(Wrappers.lambdaQuery(Pole.class).eq(Pole::getDeviceCode, deviceName));
                    if (pole != null) {
                        String testUrl = "http://www.ximonsmart.com/charge/#/charge/" + pole.getId() + "/" + System.currentTimeMillis();
                        SpringContextHolder.getBean(C3ChargingService.class).QrCode(codeRequestFrame.getDestinationAddress(), testUrl);
                if (codeRequestFrame.isValidate()) {
                    if (deviceName != null) {
                        //设置二维码
                        Pole pole = SpringContextHolder.getBean(PoleService.class).getOne(Wrappers.lambdaQuery(Pole.class).eq(Pole::getDeviceCode, deviceName));
                        if (pole != null) {
                            String testUrl = "http://www.ximonsmart.com/charge/#/charge/" + pole.getId() + "/" + System.currentTimeMillis();
                            SpringContextHolder.getBean(C3ChargingService.class).QrCode(codeRequestFrame.getDestinationAddress(), testUrl);
                        }
                    }
                }
            }
        } else if (C3ChargingEnum.HEART_BEAT.getCode().equals(functionCode)) {
            log.info("心跳相应——C3充电桩数据" + productKey + "     -------       " + deviceName);
            A5C3HeartbeatReportInnerFrame heartbeatReportInnerFrame = new A5C3HeartbeatReportInnerFrame().transformFrame(frame.getPayload());
            log.info("C3充电桩上报处理_heartbeatReportInnerFrame");
            log.info(heartbeatReportInnerFrame.toString());
            } else if (C3ChargingEnum.HEART_BEAT.getCode().equals(functionCode)) {
                log.info("心跳相应——C3充电桩数据" + productKey + "     -------       " + deviceName);
                A5C3HeartbeatReportInnerFrame heartbeatReportInnerFrame = new A5C3HeartbeatReportInnerFrame().transformFrame(frame.getPayload());
                log.info("C3充电桩上报处理_heartbeatReportInnerFrame");
                log.info(heartbeatReportInnerFrame.toString());
            if (heartbeatReportInnerFrame.isValidate()) {
                SpringContextHolder.getBean(C3ChargingService.class).updateReportState(deviceName
                        , heartbeatReportInnerFrame.getHeartBeatDataPackage().getC3Mac()
                        , heartbeatReportInnerFrame.getHeartBeatDataPackage().getStatusBit()
                        , heartbeatReportInnerFrame.getHeartBeatDataPackage().getDeviceTemperature());
                RedisUtils.getBean().set(C3mRedisConstant.C3_STATUS.getCode() + heartbeatReportInnerFrame.getHeartBeatDataPackage().getC3Mac()
                        , heartbeatReportInnerFrame.getHeartBeatDataPackage(), 300L);
            }
        } else if (C3ChargingEnum.CHARGE_COMPLETE.getCode().equals(functionCode)) {
            A5C3CommonReportInnerFrame completeRequestFrame = new A5C3CommonReportInnerFrame().transformFrame(frame.getPayload());
            log.info("C3充电桩上报处理_completeRequestFrame");
            log.info(completeRequestFrame.toString());
            //  充电结束上报(43)
            /**
             * 读取心跳包,判断剩余金额和已充电量,统计到缓存中正在进行的订单。
             */
            A5C3HeartbeatReportInnerFrame.HeartBeatDataPackage aPackage = c3ChargingService.ReadTheHeartbeatPackage(completeRequestFrame.getDestinationAddress());
            if (aPackage == null) {
                LogUtils.error("{ 充电桩(" + completeRequestFrame.getDestinationAddress() + ")充电结束上报读取心跳包失败,请检查充电桩是否出现故障! }");
                return;
            }
            refund(aPackage);
        } else if (C3ChargingEnum.CHARGE_STOP.getCode().equals(functionCode)) {
            A5C3CommonReportInnerFrame stopRequestFrame = new A5C3CommonReportInnerFrame().transformFrame(frame.getPayload());
            log.info("C3充电桩上报处理_stopRequestFrame");
            log.info(stopRequestFrame.toString());
            A5C3HeartbeatReportInnerFrame.HeartBeatDataPackage aPackage = c3ChargingService.ReadTheHeartbeatPackage(stopRequestFrame.getDestinationAddress());
            if (aPackage == null) {
                LogUtils.error("{ 充电桩(" + stopRequestFrame.getDestinationAddress() + ")充电结束上报读取心跳包失败,请检查充电桩是否出现故障! }");
                return;
            }
            refund(aPackage);
        } else if (C3ChargingEnum.ERROR_CODE.getCode().equals(functionCode)) {
            A5C3ErrorCodeReportInnerFrame errorCodeRequestFrame = new A5C3ErrorCodeReportInnerFrame().transformFrame(frame.getPayload());
            log.info("C3充电桩上报处理_errorCodeRequestFrame");
            log.info(errorCodeRequestFrame.toString());
            A5C3HeartbeatReportInnerFrame.HeartBeatDataPackage aPackage = c3ChargingService.ReadTheHeartbeatPackage(errorCodeRequestFrame.getDestinationAddress());
            if (aPackage == null) {
                LogUtils.error("{ 充电桩(" + errorCodeRequestFrame.getDestinationAddress() + ")充电结束上报读取心跳包失败,请检查充电桩是否出现故障! }");
                return;
            }
            refund(aPackage);
        } else if (C3ChargingEnum.StartCharging.getCode().equals(functionCode)) {
            log.info("心跳响应——C3充电桩开始充电");
            A5C3OperationReportInnerFrame operationReportInnerFrame = new A5C3OperationReportInnerFrame().transformFrame(frame.getPayload());
            log.info("C3充电桩上报处理_heartbeatReportInnerFrame");
            log.info(operationReportInnerFrame.toString());
//            if (operationReportInnerFrame.isValidate()) {
//                SpringContextHolder.getBean(C3ChargingService.class).saveReportData(deviceName, operationReportInnerFrame.getHeartBeatDataPackage());
//            }
        }
    }
    private void refund(A5C3HeartbeatReportInnerFrame.HeartBeatDataPackage aPackage) {
//    private void refund(A5C3CommonReportInnerFrame completeRequestFrame,String code){
        /**
         * 读取心跳包,判断剩余金额和已充电量,统计到缓存中正在进行的订单。
         */
        String c3Mac = aPackage.getC3Mac();
        //  获取心跳包中的剩余金额和已充电量,与缓存中正在进行的订单进行对比
        String chargingOrderJson = RedisUtils.getBean().get(C3mRedisConstant.C3_CHARGING_ORDER.getCode() + c3Mac);
        if (chargingOrderJson.isEmpty() || null == chargingOrderJson) {
            C3mCharging c3m = c3ChargingService.getOne(Wrappers.lambdaQuery(C3mCharging.class).eq(C3mCharging::getC3Mac, c3Mac));
            PoleBinding binding = bindingService.getOne(Wrappers.lambdaQuery(PoleBinding.class)
                    .eq(PoleBinding::getDeviceCode, aPackage.getC3Mac())
                    .eq(PoleBinding::getDeviceType, 2));
            //  生成订单,并加载到redis缓存,设置超时时间为5分钟
            C3mOrder order = new C3mOrderVO().generateOrder(binding.getPoleId() == null ? 0L : binding.getPoleId()
                    , c3m.getPoleDevicesCode(), c3m.getC3Mac(), OrderType.ERROR, Double.valueOf(aPackage.getRemainingAmount()),
                    Integer.parseInt(new java.text.DecimalFormat("0").format(aPackage.getReservedCapacity()))
            );
            order.setActualChargingCapacity(Double.valueOf(aPackage.getChargedCapacity()));
            order.setOrderStatus(OrderStatus.REFUNDING.getStatus());
            order.setRefundAmount(Double.valueOf(aPackage.getRemainingAmount()));
            orderService.save(order);
            String s = c3ChargingService.finishCharging(c3Mac);
//            if(C3ChargingEnum.CHARGE_COMPLETE.getCode().equals(code)){
//
//            }
            //是否需要区分log类型 待定
            LogUtils.error("{ 充电桩(" + c3Mac + ")不存在正在进行的订单,请检查充电桩是否出现故障!结束订单,结果为" + s + "}");
        } else {
            C3mOrder c3mOrderEntity = JSON.parseObject(chargingOrderJson, C3mOrder.class);
            //  设置已充电量,订单状态,退款金额,订单退款时间戳,订单退款说明,结束充电时间戳,
            c3mOrderEntity.setActualChargingCapacity(Double.valueOf(aPackage.getChargedCapacity()));
            c3mOrderEntity.setOrderStatus(OrderStatus.REFUNDING.getStatus());
            c3mOrderEntity.setRefundAmount(Double.valueOf(aPackage.getRemainingAmount()));
            //  获取剩余金额进行退款,并写入当前正在进行的订单
            boolean b = orderService.orderRefund(c3mOrderEntity.getOutTradeNo(), c3mOrderEntity.getRefundAmount());
            c3mOrderEntity.setRefundTimestamp(new Date().getTime());
            if (b) {
                c3mOrderEntity.setOrderStatus(OrderStatus.REFUND.getStatus());
                c3mOrderEntity.setRefundMsg("充电结束,订单退款成功");
            } else {
                c3mOrderEntity.setOrderStatus(OrderStatus.REFUND_FAILED.getStatus());
                c3mOrderEntity.setRefundMsg(
                        "充电结束,订单退款失败,请进行手动退款(订单号(" +
                                c3mOrderEntity.getOutTradeNo() + "),总金额(" +
                                c3mOrderEntity.getTotalAmount() + ",退款金额(" +
                                aPackage.getRemainingAmount() + "))"
                );
            }
            c3mOrderEntity.setStopChargingTimestamp(new Date().getTime());
            orderService.updateById(c3mOrderEntity);
            //  清除缓存中正在进行中的订单
            b = RedisUtils.getBean().delete(C3mRedisConstant.C3_CHARGING_ORDER.getCode() + c3mOrderEntity.getC3Mac());
            if (!b) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                if (heartbeatReportInnerFrame.isValidate()) {
                    SpringContextHolder.getBean(C3ChargingService.class).updateReportState(deviceName
                            , heartbeatReportInnerFrame.getHeartBeatDataPackage().getC3Mac()
                            , heartbeatReportInnerFrame.getHeartBeatDataPackage().getStatusBit()
                            , heartbeatReportInnerFrame.getHeartBeatDataPackage().getDeviceTemperature());
                    //更新订单数据
                    SpringContextHolder.getBean(C3mOrderService.class).updateOrderStatusByHeartbeat(heartbeatReportInnerFrame.getHeartBeatDataPackage());
                    //存缓存
                    RedisUtils.getBean().set(C3mRedisConstant.C3_STATUS.getCode() + heartbeatReportInnerFrame.getHeartBeatDataPackage().getC3Mac()
                            , heartbeatReportInnerFrame.getHeartBeatDataPackage(), 300L);
                }
                RedisUtils.getBean().delete(C3mRedisConstant.C3_CHARGING_ORDER.getCode() + c3mOrderEntity.getC3Mac());
            }
            //  发送结束订单
            String s = c3ChargingService.finishCharging(c3Mac);
            LogUtils.error("{ 充电桩(" + c3Mac + ")不存在正在进行的订单,请检查充电桩是否出现故障!结束订单,结果为" + s + "}");
        }
            } else if (C3ChargingEnum.CHARGE_COMPLETE.getCode().equals(functionCode)) {
                A5C3CommonReportInnerFrame completeRequestFrame = new A5C3CommonReportInnerFrame().transformFrame(frame.getPayload());
                log.info("C3充电桩上报处理_completeRequestFrame");
                log.info(completeRequestFrame.toString());
                //  充电结束上报(43)
                /**
                 * 读取心跳包,判断剩余金额和已充电量,统计到缓存中正在进行的订单。
                 */
                A5C3HeartbeatReportInnerFrame.HeartBeatDataPackage aPackage = c3ChargingService.ReadTheHeartbeatPackage(completeRequestFrame.getDestinationAddress(), true);
                if (aPackage == null) {
                    LogUtils.error("{ 充电桩(" + completeRequestFrame.getDestinationAddress() + ")充电结束上报读取心跳包失败,请检查充电桩是否出现故障! }");
                    return;
                }
                orderService.stopCharingOrder(aPackage);
            } else if (C3ChargingEnum.CHARGE_STOP.getCode().equals(functionCode)) {
                log.info("心跳响应——充电中断");
                A5C3CommonReportInnerFrame stopRequestFrame = new A5C3CommonReportInnerFrame().transformFrame(frame.getPayload());
                log.info("C3充电桩上报处理_stopRequestFrame");
                log.info(stopRequestFrame.toString());
                /**
                 * 读取心跳包,判断剩余金额和已充电量,统计到缓存中正在进行的订单。
                 */
                A5C3HeartbeatReportInnerFrame.HeartBeatDataPackage aPackage = c3ChargingService.ReadTheHeartbeatPackage(stopRequestFrame.getDestinationAddress(), true);
                if (aPackage == null) {
                    LogUtils.error("{ 充电桩(" + stopRequestFrame.getDestinationAddress() + ")充电结束上报读取心跳包失败,请检查充电桩是否出现故障! }");
                    return;
                }
                orderService.stopCharingOrder(aPackage);
            } else if (C3ChargingEnum.ERROR_CODE.getCode().equals(functionCode)) {
                log.info("心跳响应——故障");
                A5C3ErrorCodeReportInnerFrame errorCodeRequestFrame = new A5C3ErrorCodeReportInnerFrame().transformFrame(frame.getPayload());
                log.info("C3充电桩上报处理_errorCodeRequestFrame");
                log.info(errorCodeRequestFrame.toString());
                /**
                 * 保存C3充电桩故障数据
                 */
                if (errorCodeRequestFrame.isValidate() && errorCodeRequestFrame.getErrorMessage() != null) {
                    //保存故障信息
                    SpringContextHolder.getBean(C3mReportErrorService.class).saveReportError(errorCodeRequestFrame);
//                //充电桩故障结束订单
//                A5C3HeartbeatReportInnerFrame.HeartBeatDataPackage aPackage = c3ChargingService.ReadTheHeartbeatPackage(errorCodeRequestFrame.getDestinationAddress(), true);
//                if (aPackage == null) {
//                    LogUtils.error("{ 充电桩(" + errorCodeRequestFrame.getDestinationAddress() + ")故障上报读取心跳包失败,请检查充电桩是否出现故障! }");
//                    return;
//                }
//                orderService.stopCharingOrder(aPackage);
                } else {
                    System.out.println("数据校验异常!");
                }
            }
        } else {
            log.info("不要处理0000048A之外的充电桩!");
            return;
        }
    }
}