puzhibing
2026-09-09 4a5e1477afc559cf870b34e4693f41d85e9580d1
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/task/TaskUtil.java
@@ -96,6 +96,12 @@
    private SiteClient siteClient;
    @Resource
    private TChargingOrderService chargingOrderService;
    @Resource
    private TCardChargingOrderService cardChargingOrderService;
    @Resource
    private TVinChargingOrderService vinChargingOrderService;
    
    @Resource
    private TChargingOrderRefundService chargingOrderRefundService;
@@ -283,6 +289,92 @@
        }
    }
    /**
     * 刷卡/VIN 订单超时补偿(文档13.3 定时任务补偿路径,10分钟一轮):
     * 1) 启动中超时(状态2超30分钟未收到启动成功应答)→ 关单(状态6)+解锁卡片+复位枪;
     * 2) 充电中超时(状态3/4超24小时未收到交易记录)→ 以订单累计电量构造平段账单,
     *    复用统一结算入口兜底结算(结算锁/状态幂等/扣款幂等全复用)
     */
    @Scheduled(fixedRate = 1000 * 60 * 10, initialDelay = 1000 * 60)
    public void cardVinOrderCompensationTask() {
        if (isScheduledTaskPort(port)) {
            compensateCardOrders();
            compensateVinOrders();
        }
    }
    /**
     * SD 刷卡订单超时补偿
     */
    private void compensateCardOrders() {
        try {
            List<TCardChargingOrder> startingOrders = cardChargingOrderService.listTimeoutStartingOrders();
            if (!startingOrders.isEmpty()) {
                log.info("[SD补偿] 启动超时订单数量:{}", startingOrders.size());
                for (TCardChargingOrder order : startingOrders) {
                    try {
                        cardChargingOrderService.closeTimeoutStartingOrder(order);
                    } catch (Exception ex) {
                        log.error("[SD补偿] 启动超时关单失败 code={}", order.getCode(), ex);
                    }
                }
            }
        } catch (Exception e) {
            log.error("[SD补偿] 启动超时扫描异常", e);
        }
        try {
            List<TCardChargingOrder> chargingOrders = cardChargingOrderService.listTimeoutChargingOrders();
            if (!chargingOrders.isEmpty()) {
                log.info("[SD补偿] 充电超时订单数量:{}", chargingOrders.size());
                for (TCardChargingOrder order : chargingOrders) {
                    try {
                        cardChargingOrderService.compensationSettle(order);
                    } catch (Exception ex) {
                        log.error("[SD补偿] 充电超时兜底结算失败 code={}", order.getCode(), ex);
                    }
                }
            }
        } catch (Exception e) {
            log.error("[SD补偿] 充电超时扫描异常", e);
        }
    }
    /**
     * VD VIN码订单超时补偿
     */
    private void compensateVinOrders() {
        try {
            List<TVinChargingOrder> startingOrders = vinChargingOrderService.listTimeoutStartingOrders();
            if (!startingOrders.isEmpty()) {
                log.info("[VD补偿] 启动超时订单数量:{}", startingOrders.size());
                for (TVinChargingOrder order : startingOrders) {
                    try {
                        vinChargingOrderService.closeTimeoutStartingOrder(order);
                    } catch (Exception ex) {
                        log.error("[VD补偿] 启动超时关单失败 code={}", order.getCode(), ex);
                    }
                }
            }
        } catch (Exception e) {
            log.error("[VD补偿] 启动超时扫描异常", e);
        }
        try {
            List<TVinChargingOrder> chargingOrders = vinChargingOrderService.listTimeoutChargingOrders();
            if (!chargingOrders.isEmpty()) {
                log.info("[VD补偿] 充电超时订单数量:{}", chargingOrders.size());
                for (TVinChargingOrder order : chargingOrders) {
                    try {
                        vinChargingOrderService.compensationSettle(order);
                    } catch (Exception ex) {
                        log.error("[VD补偿] 充电超时兜底结算失败 code={}", order.getCode(), ex);
                    }
                }
            }
        } catch (Exception e) {
            log.error("[VD补偿] 充电超时扫描异常", e);
        }
    }
    //十分钟循环执行的定时任务
    @Scheduled(fixedRate = 1000 * 60 * 10)