puzhibing
2 小时以前 eb2b04d95bb70378f60eaa70bfda8e4c7f08846a
修改bug
1个文件已修改
56 ■■■■■ 已修改文件
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -2033,6 +2033,11 @@
        chargingOrder.setVipDiscountAmount(discountAmount);
        this.updateById(chargingOrder);
        // 支付成功立即下发启动充电指令(恢复 master 时序:桩收到指令后再做安全检测并回启动应答)。
        // 预约订单不在此处下发,由 startDueReservationOrders 到期后统一下发。
        if (chargingOrder.getReservationTime() == null) {
            startCharging(chargingOrder, preChargeCheck);
        }
        return AjaxResult.success();
    }
@@ -2067,13 +2072,6 @@
                    + ReservationTimeRangeSupport.describe(ranges) + ")");
        }
        return null;
    }
    private boolean isSafetyCheckPassed(PreChargeCheck check) {
        return check != null
                && Boolean.TRUE.equals(check.getElectronicLockLock())
                && Boolean.TRUE.equals(check.getInsulationTesting())
                && Boolean.TRUE.equals(check.getSecureConnectionDetection());
    }
    /**
@@ -2123,9 +2121,11 @@
        for (TChargingOrder order : dueOrders) {
            try {
                PreChargeCheck check = redisService.getCacheObject("AQJC_" + order.getChargingGunId());
                if (isSafetyCheckPassed(check)) {
                    startChargingAfterSafety(order, check);
                if (null == check) {
                    check = newPreChargeCheck(order);
                }
                // 预约到期后直接下发启动指令,无需等待安全检测通过
                startCharging(order, check);
            } catch (Exception e) {
                log.error("预约充电到时启动失败,orderCode={}", order.getCode(), e);
            }
@@ -2170,43 +2170,44 @@
        }
    }
    private void startChargingAfterSafety(TChargingOrder chargingOrder, PreChargeCheck check) {
    private void startCharging(TChargingOrder chargingOrder, PreChargeCheck check) {
        RLock lock = redissonClient.getLock("START_AFTER_SAFETY:" + chargingOrder.getId());
        try {
            if (!lock.tryLock(1, 10, TimeUnit.SECONDS)) {
                return;
            }
            TChargingOrder latest = this.getById(chargingOrder.getId());
            if (latest == null || latest.getStatus() != 2 || Boolean.TRUE.equals(check.getStartCommandSent())) {
            // 直接使用传入对象:支付完成/预约到期路径下传入对象已是当前最新状态,
            // 避免读写分离下 this.getById 立即回查读不到刚提交的 status=2 导致指令不下发
            if (chargingOrder == null || chargingOrder.getStatus() != 2 || Boolean.TRUE.equals(check.getStartCommandSent())) {
                return;
            }
            if (!ReservationOrderSupport.isStartDue(latest.getReservationTime(), LocalDateTime.now())) {
            if (!ReservationOrderSupport.isStartDue(chargingOrder.getReservationTime(), LocalDateTime.now())) {
                return;
            }
            TChargingGun gun = chargingGunClient.getChargingGunById(latest.getChargingGunId()).getData();
            TChargingGun gun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
            TChargingPile pile = chargingPileClient.getChargingPileById(gun.getChargingPileId()).getData();
            String actualVin = normalizeVin(check.getActualVin());
            PlatformStartCharging command = new PlatformStartCharging();
            command.setTransaction_serial_number(latest.getCode());
            command.setTransaction_serial_number(chargingOrder.getCode());
            command.setCharging_pile_code(pile.getCode());
            command.setCharging_gun_code(gun.getCode());
            command.setCard_number(latest.getId().toString());
            command.setAccount_balance(latest.getChargeAmount());
            latest.setActualVin(actualVin);
            this.updateById(latest);
            log.info(latest.getCode() + ":安全检测通过,下发启动充电命令:" + command);
            command.setCard_number(chargingOrder.getId().toString());
            command.setAccount_balance(chargingOrder.getChargeAmount());
            chargingOrder.setActualVin(actualVin);
            this.updateById(chargingOrder);
            log.info(chargingOrder.getCode() + ":下发启动充电命令:" + command);
            try {
                sendMessageClient.platformStartCharging(command);
            } catch (Exception e) {
                // 下发失败不置 startCommandSent:保留后续安全检测上报重试机会,超时订单由兜底任务取消
                log.error(latest.getCode() + ":启动充电命令下发失败,等待下次安全检测上报重试", e);
                // 下发失败不置 startCommandSent:由启动超时兜底任务取消订单并退款
                log.error(chargingOrder.getCode() + ":启动充电命令下发失败,交由启动超时兜底任务处理", e);
                return;
            }
            check.setStartCommandSent(true);
            redisService.setCacheObject("AQJC_" + latest.getChargingGunId(), check, 24L, TimeUnit.HOURS);
            redisService.setCacheObject("AQJC_" + chargingOrder.getChargingGunId(), check, 24L, TimeUnit.HOURS);
            ScheduledExecutorService resultScheduler = Executors.newScheduledThreadPool(1);
            resultScheduler.scheduleAtFixedRate(() -> {
                if (timingDetection(latest.getId())) {
                if (timingDetection(chargingOrder.getId())) {
                    resultScheduler.shutdown();
                }
            }, 10, 1, TimeUnit.SECONDS);
@@ -2421,12 +2422,7 @@
        // 刷新等待基准时间,避免前端等待窗口/超时判断误伤正在推进的安全检测
        preChargeCheck1.setAddTime(LocalDateTime.now());
        redisService.setCacheObject(key, preChargeCheck1, 24L, TimeUnit.HOURS);
        if (isSafetyCheckPassed(preChargeCheck1)) {
            TChargingOrder pendingOrder = getPendingStartOrder(chargingGun.getId());
            if (pendingOrder != null) {
                startChargingAfterSafety(pendingOrder, preChargeCheck1);
            }
        }
        // 启动指令已在支付完成/预约到期时下发,此处仅记录检测结果,不再触发启动
    }
    /**