puzhibing
2026-09-15 262eb0096f28537c2859f79cdfa466092dc4f898
修改bug
3个文件已修改
60 ■■■■■ 已修改文件
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TVinChargingOrderServiceImpl.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/service/impl/CardVinOrderCompensationTest.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/service/impl/CardVinSettlementTimeAlignmentTest.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TVinChargingOrderServiceImpl.java
@@ -1068,6 +1068,8 @@
        final BigDecimal totalElec = totalElectricity;
        final BigDecimal elecTotal = electrovalenceTotal;
        final BigDecimal svcTotal = serviceChargeTotal;
        final BigDecimal startSoc = getMonitoringSocQuietly(code, "asc");
        final BigDecimal endSoc = getMonitoringSocQuietly(code, "desc");
        // 本地事务:写计费明细 + 更新订单(状态5;VD后付记账模式,不做账户扣款)
        transactionTemplate.execute(status -> {
@@ -1085,6 +1087,12 @@
            update.setServiceCharge(svcTotal);
            update.setOrderAmount(orderAmount);
            update.setPaymentAmount(orderAmount);
            if (startSoc != null) {
                update.setStartSoc(startSoc);
            }
            if (endSoc != null) {
                update.setEndSoc(endSoc);
            }
            update.setEndTime(parseDeviceTime(vo.getEnd_time(), LocalDateTime.now()));
            if (order.getStartTime() == null) {
                update.setStartTime(parseDeviceTime(vo.getStart_time(), null));
@@ -1209,6 +1217,23 @@
        }
    }
    /**
     * 容错读取订单最早/最新监控记录的 SOC;Mongo 数据缺失或查询异常不阻断主结算流程。
     */
    private BigDecimal getMonitoringSocQuietly(String code, String sort) {
        if (monitoringDataService == null) {
            return null;
        }
        try {
            UploadRealTimeMonitoringData monitoringData = monitoringDataService.getDataByOrderCode(code, sort);
            return monitoringData == null || monitoringData.getSoc() == null
                    ? null : BigDecimal.valueOf(monitoringData.getSoc().longValue());
        } catch (Exception ex) {
            log.error("[VD结算] 查询监控SOC失败 code={} sort={}", code, sort, ex);
            return null;
        }
    }
    private LocalDateTime parseDeviceTime(String value, LocalDateTime fallback) {
        if (StringUtils.isEmpty(value)) {
            return fallback;
ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/service/impl/CardVinOrderCompensationTest.java
@@ -22,6 +22,7 @@
import com.ruoyi.order.service.TCardChargingOrderAccountingStrategyService;
import com.ruoyi.order.service.TVinAccountingStrategyDetailOrderService;
import com.ruoyi.order.service.TVinChargingOrderAccountingStrategyService;
import com.ruoyi.order.util.mongodb.service.UploadRealTimeMonitoringDataService;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@@ -277,8 +278,10 @@
        TVinChargingOrderServiceImpl service = new TVinChargingOrderServiceImpl();
        TVinChargingOrderMapper mapper = mock(TVinChargingOrderMapper.class);
        ChargingGunClient gunClient = mock(ChargingGunClient.class);
        UploadRealTimeMonitoringDataService monitoringDataService = mock(UploadRealTimeMonitoringDataService.class);
        ReflectionTestUtils.setField(service, "baseMapper", mapper);
        ReflectionTestUtils.setField(service, "chargingGunClient", gunClient);
        ReflectionTestUtils.setField(service, "monitoringDataService", monitoringDataService);
        ReflectionTestUtils.setField(service, "redissonClient", mockedRedisson(mockedLock(true)));
        TVinChargingOrder finished = new TVinChargingOrder();
@@ -296,6 +299,7 @@
        assertEquals(R.SUCCESS, result.getCode());
        verify(gunClient, never()).updateChargingGunById(any(TChargingGun.class));
        verifyNoInteractions(monitoringDataService);
    }
    // ===== VD:结算明细补齐计费策略明细id与首次添加时间 =====
ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/service/impl/CardVinSettlementTimeAlignmentTest.java
@@ -10,6 +10,7 @@
import com.ruoyi.chargingPile.api.feignClient.ChargingGunClient;
import com.ruoyi.chargingPile.api.model.TChargingGun;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.integration.api.model.UploadRealTimeMonitoringData;
import com.ruoyi.order.api.model.TCardAccountingStrategyDetailOrder;
import com.ruoyi.order.api.model.TCardChargingOrder;
import com.ruoyi.order.api.model.TCardChargingOrderAccountingStrategy;
@@ -23,6 +24,7 @@
import com.ruoyi.order.service.TCardChargingOrderAccountingStrategyService;
import com.ruoyi.order.service.TVinAccountingStrategyDetailOrderService;
import com.ruoyi.order.service.TVinChargingOrderAccountingStrategyService;
import com.ruoyi.order.util.mongodb.service.UploadRealTimeMonitoringDataService;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@@ -45,6 +47,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
@@ -268,11 +271,13 @@
        TVinChargingOrderServiceImpl service = new TVinChargingOrderServiceImpl();
        TVinChargingOrderMapper mapper = mock(TVinChargingOrderMapper.class);
        ChargingGunClient gunClient = mock(ChargingGunClient.class);
        UploadRealTimeMonitoringDataService monitoringDataService = mock(UploadRealTimeMonitoringDataService.class);
        TVinAccountingStrategyDetailOrderService detailOrderService = mock(TVinAccountingStrategyDetailOrderService.class);
        TVinChargingOrderAccountingStrategyService strategyService = mock(TVinChargingOrderAccountingStrategyService.class);
        TransactionTemplate txTemplate = mock(TransactionTemplate.class);
        ReflectionTestUtils.setField(service, "baseMapper", mapper);
        ReflectionTestUtils.setField(service, "chargingGunClient", gunClient);
        ReflectionTestUtils.setField(service, "monitoringDataService", monitoringDataService);
        ReflectionTestUtils.setField(service, "vinAccountingStrategyDetailOrderService", detailOrderService);
        ReflectionTestUtils.setField(service, "vinChargingOrderAccountingStrategyService", strategyService);
        ReflectionTestUtils.setField(service, "transactionTemplate", txTemplate);
@@ -287,6 +292,12 @@
        charging.setEndTime(LocalDateTime.of(2026, 9, 14, 21, 45, 0));
        when(mapper.selectOne(any())).thenReturn(charging);
        when(mapper.updateById(any())).thenReturn(1);
        UploadRealTimeMonitoringData firstMonitoring = new UploadRealTimeMonitoringData();
        firstMonitoring.setSoc(18);
        UploadRealTimeMonitoringData lastMonitoring = new UploadRealTimeMonitoringData();
        lastMonitoring.setSoc(87);
        when(monitoringDataService.getDataByOrderCode("VD1", "asc")).thenReturn(firstMonitoring);
        when(monitoringDataService.getDataByOrderCode("VD1", "desc")).thenReturn(lastMonitoring);
        stubGunAndUpdate(gunClient, 7);
        stubVinStrategyQuerySave(detailOrderService, strategyService, vinThreePeriodSnapshots());
@@ -301,6 +312,13 @@
        R result = service.vinEndChargeBillingCharge(vo);
        assertEquals(R.SUCCESS, result.getCode());
        ArgumentCaptor<TVinChargingOrder> orderCaptor = ArgumentCaptor.forClass(TVinChargingOrder.class);
        verify(mapper).updateById(orderCaptor.capture());
        assertEquals(0, new BigDecimal("18").compareTo(orderCaptor.getValue().getStartSoc()));
        assertEquals(0, new BigDecimal("87").compareTo(orderCaptor.getValue().getEndSoc()));
        verify(monitoringDataService).getDataByOrderCode("VD1", "asc");
        verify(monitoringDataService).getDataByOrderCode("VD1", "desc");
        ArgumentCaptor<Collection<TVinChargingOrderAccountingStrategy>> captor = ArgumentCaptor.forClass(Collection.class);
        verify(strategyService).saveBatch(captor.capture());
@@ -336,11 +354,13 @@
        TVinChargingOrderServiceImpl service = new TVinChargingOrderServiceImpl();
        TVinChargingOrderMapper mapper = mock(TVinChargingOrderMapper.class);
        ChargingGunClient gunClient = mock(ChargingGunClient.class);
        UploadRealTimeMonitoringDataService monitoringDataService = mock(UploadRealTimeMonitoringDataService.class);
        TVinAccountingStrategyDetailOrderService detailOrderService = mock(TVinAccountingStrategyDetailOrderService.class);
        TVinChargingOrderAccountingStrategyService strategyService = mock(TVinChargingOrderAccountingStrategyService.class);
        TransactionTemplate txTemplate = mock(TransactionTemplate.class);
        ReflectionTestUtils.setField(service, "baseMapper", mapper);
        ReflectionTestUtils.setField(service, "chargingGunClient", gunClient);
        ReflectionTestUtils.setField(service, "monitoringDataService", monitoringDataService);
        ReflectionTestUtils.setField(service, "vinAccountingStrategyDetailOrderService", detailOrderService);
        ReflectionTestUtils.setField(service, "vinChargingOrderAccountingStrategyService", strategyService);
        ReflectionTestUtils.setField(service, "transactionTemplate", txTemplate);
@@ -351,9 +371,11 @@
        charging.setCode("VD1");
        charging.setStatus(4);
        charging.setChargingGunId(7);
        // startTime/endTime 均为 null
        // startTime/endTime 均为 null,Mongo 首末监控记录也不存在
        when(mapper.selectOne(any())).thenReturn(charging);
        when(mapper.updateById(any())).thenReturn(1);
        when(monitoringDataService.getDataByOrderCode("VD1", "asc")).thenReturn(null);
        when(monitoringDataService.getDataByOrderCode("VD1", "desc")).thenReturn(null);
        stubGunAndUpdate(gunClient, 7);
        stubVinStrategyQuerySave(detailOrderService, strategyService, vinThreePeriodSnapshots());
@@ -368,6 +390,13 @@
        R result = service.vinEndChargeBillingCharge(vo);
        assertEquals(R.SUCCESS, result.getCode());
        ArgumentCaptor<TVinChargingOrder> orderCaptor = ArgumentCaptor.forClass(TVinChargingOrder.class);
        verify(mapper).updateById(orderCaptor.capture());
        assertNull(orderCaptor.getValue().getStartSoc());
        assertNull(orderCaptor.getValue().getEndSoc());
        verify(monitoringDataService).getDataByOrderCode("VD1", "asc");
        verify(monitoringDataService).getDataByOrderCode("VD1", "desc");
        ArgumentCaptor<Collection<TVinChargingOrderAccountingStrategy>> captor = ArgumentCaptor.forClass(Collection.class);
        verify(strategyService).saveBatch(captor.capture());
        List<TVinChargingOrderAccountingStrategy> saved = new ArrayList<>(captor.getValue());