2021与蓝度共同重构项目,服务端
zhanzhiqin
2022-08-31 65ffc54ad3145eaecbbfe687f7557b95514205a6
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/amqp/processor/c3ChargingProcessor.java
@@ -1,6 +1,5 @@
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.manager.iot.frame.inner.report.A5C3CommonReportInnerFrame;
@@ -10,24 +9,17 @@
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.math.BigDecimal;
import java.util.Date;
/**
 * @author ZZQ
@@ -59,194 +51,127 @@
    @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) {
                    C3mCharging c3mCharging = SpringContextHolder.getBean(C3ChargingService.class).
                            getOne(Wrappers.lambdaQuery(C3mCharging.class).eq(C3mCharging::getC3Mac, codeRequestFrame.getDestinationAddress()).last("limit 1"));
                    if(c3mCharging == null){
                        SpringContextHolder.getBean(C3ChargingService.class).saveReporEquipment(deviceName, codeRequestFrame.getMcuUdid(), codeRequestFrame.getDestinationAddress());
                    }
                    //设置二维码
                    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());
                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);
                }
            } else if (C3ChargingEnum.CHARGE_COMPLETE.getCode().equals(functionCode)) {
                A5C3CommonReportInnerFrame completeRequestFrame = new A5C3CommonReportInnerFrame().transformFrame(frame.getPayload());
                log.info("C3充电桩上报处理_completeRequestFrame");
                log.info(completeRequestFrame.toString());
                //  充电结束上报(43)
                /**
                 * 读取心跳包,判断剩余金额和已充电量,统计到缓存中正在进行的订单。
                 */
                if (completeRequestFrame != null) {
                    C3mCharging one = SpringContextHolder.getBean(C3ChargingService.class).
                            getOne(Wrappers.lambdaQuery(C3mCharging.class).eq(C3mCharging::getMcuUdid, completeRequestFrame.getMcuUdid()).last("limit 1"));
                    if (one == null) {
                        return;
                    }
                    A5C3HeartbeatReportInnerFrame.HeartBeatDataPackage aPackage = c3ChargingService.ReadTheHeartbeatPackage(one.getC3Id(), 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());
                if (stopRequestFrame != null) {
                    C3mCharging one = SpringContextHolder.getBean(C3ChargingService.class).
                            getOne(Wrappers.lambdaQuery(C3mCharging.class).eq(C3mCharging::getMcuUdid, stopRequestFrame.getMcuUdid()).last("limit 1"));
                    if (one == null) {
                        return;
                    }
                    /**
                     * 读取心跳包,判断剩余金额和已充电量,统计到缓存中正在进行的订单。
                     */
                    A5C3HeartbeatReportInnerFrame.HeartBeatDataPackage aPackage = c3ChargingService.ReadTheHeartbeatPackage(one.getC3Id(), 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 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());
                //更新订单数据
                SpringContextHolder.getBean(C3mOrderService.class).updateOrderStatusByHeartbeat(heartbeatReportInnerFrame.getHeartBeatDataPackage());
                //存缓存
                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);
            orderProcess(aPackage.getC3Mac());
        } 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());
            //充电结束  更新订单状态
//            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());
        }
    }
    private void refund(A5C3HeartbeatReportInnerFrame.HeartBeatDataPackage aPackage) {
        /**
         * 读取心跳包,判断剩余金额和已充电量,统计到缓存中正在进行的订单。
         */
        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();
                }
                RedisUtils.getBean().delete(C3mRedisConstant.C3_CHARGING_ORDER.getCode() + c3mOrderEntity.getC3Mac());
            }
            //  发送结束订单
            String s = c3ChargingService.finishCharging(c3Mac);
            LogUtils.error("{ 充电桩(" + c3Mac + ")不存在正在进行的订单,请检查充电桩是否出现故障!结束订单,结果为" + s + "}");
        }
    }
    /**
     * 订单处理
     *
     * @param c3Mac
     */
    private void orderProcess(String c3Mac) {
        //结束充电 更改订单状态
        C3mOrder lastOrderByC3Mac = SpringContextHolder.getBean(C3mOrderService.class).getLastOrderByC3Mac(c3Mac);
        if (lastOrderByC3Mac != null) {
            //设置订单状态为已完成
            lastOrderByC3Mac.setOrderStatus(OrderStatus.COMPLETE.getStatus());
            BigDecimal actualChargingCapacity = BigDecimal.valueOf(lastOrderByC3Mac.getActualChargingCapacity());
            BigDecimal actualChargingCapacityHide = BigDecimal.valueOf(lastOrderByC3Mac.getActualChargingCapacityHide());
            //设置实际充电电量
            lastOrderByC3Mac.setActualChargingCapacity(actualChargingCapacity.add(actualChargingCapacityHide).doubleValue());
            //设置订单结束时间
            lastOrderByC3Mac.setStopChargingTimestamp(System.currentTimeMillis());
            lastOrderByC3Mac.setActualChargingCapacity(0.00);
            //设置订单状态为充电结束
            lastOrderByC3Mac.setChargingStates(1);
            SpringContextHolder.getBean(C3mOrderService.class).updateById(lastOrderByC3Mac);
            log.info("不要处理0000048A之外的充电桩!");
            return;
        }
    }
}