puzhibing
2026-09-04 8492398378af25d7aa9598c79ea7aeb737d91d76
VIN充电增加详情查询接口
4个文件已修改
174 ■■■■■ 已修改文件
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TVinChargingOrderController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TVinChargingOrderService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TVinChargingOrderServiceImpl.java 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/service/impl/TVinChargingOrderAppletServiceTest.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TVinChargingOrderController.java
@@ -68,6 +68,13 @@
        return R.ok(vinChargingOrderService.pageAppletOrders(pageCurr, pageSize));
    }
    @GetMapping("/applet/detail")
    @ApiOperation(value = "当前用户VIN码充电订单详情", tags = {"小程序-充电记录"})
    public R<Map<String, Object>> appletDetail(@RequestParam("id") Long id) {
        Map<String, Object> detail = vinChargingOrderService.appletDetail(id);
        return detail.isEmpty() ? R.fail("VIN码充电订单不存在或无权查看") : R.ok(detail);
    }
    @RequiresPermissions("/vinChargingOrder/list")
    @GetMapping("/summary")
    @ApiOperation("VIN码充电订单汇总")
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TVinChargingOrderService.java
@@ -18,6 +18,8 @@
    PageInfo<MyVinChargingOrderList> pageAppletOrders(Integer pageCurr, Integer pageSize);
    Map<String, Object> appletDetail(Long chargingOrderId);
    List<VinChargingStatusVO> getChargingVinStatus(List<Long> vinIds);
    List<ChargingOrderVO> exportList(VinChargingOrderQuery query);
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TVinChargingOrderServiceImpl.java
@@ -28,7 +28,11 @@
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Collections;
@@ -99,6 +103,44 @@
        fillAppletExtra(records);
        page.setRecords(records);
        return page;
    }
    @Override
    public Map<String, Object> appletDetail(Long chargingOrderId) {
        TVinChargingOrder order = getAuthorizedAppletOrder(chargingOrderId);
        if (order == null) {
            return Collections.emptyMap();
        }
        Map<String, Object> result = new HashMap<>();
        result.put("id", String.valueOf(order.getId()));
        result.put("chargingGunId", order.getChargingGunId());
        result.put("code", order.getCode());
        result.put("createTime", order.getCreateTime() == null ? null
                : order.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        result.put("status", order.getStatus());
        result.put("licensePlate", order.getPlateNum());
        result.put("startTime", toEpochMilli(order.getStartTime()));
        result.put("endTime", toEpochMilli(order.getEndTime()));
        result.put("orderAmount", order.getOrderAmount());
        result.put("paymentAmount", order.getPaymentAmount());
        result.put("rechargeAmount", order.getRechargeAmount());
        result.put("couponDiscountAmount", order.getCouponDiscountAmount());
        result.put("vipDiscountAmount", order.getVipDiscountAmount());
        result.put("refundAmount", order.getRefundAmount());
        result.put("electricMoney", order.getElectrovalence());
        result.put("serviceMoney", order.getServiceCharge());
        result.put("totalElectricQuantity", order.getChargingCapacity());
        result.put("stageCost", baseMapper.accountingStrategyList(order.getId()));
        result.put("actionable", 0);
        result.put("isAppeal", 0);
        Site site = getSite(order.getSiteId());
        result.put("title", site == null ? "未知电站" : site.getName());
        TChargingGun gun = getGun(order.getChargingGunId());
        result.put("chargeMode", gun == null ? null : gun.getChargeMode());
        result.put("name", gun == null ? null : gun.getName());
        fillAppletMonitoring(result, order.getCode());
        return result;
    }
    @Override
@@ -264,6 +306,82 @@
                .orElse(Collections.emptyList()).stream().map(GetSiteListDTO::getId).collect(Collectors.toList());
    }
    private TVinChargingOrder getAuthorizedAppletOrder(Long chargingOrderId) {
        if (chargingOrderId == null || tokenService.getLoginUserApplet() == null
                || tokenService.getLoginUserApplet().getUserId() == null) {
            return null;
        }
        TVinChargingOrder order = getById(chargingOrderId);
        if (order == null || order.getVinId() == null) {
            return null;
        }
        R<List<Long>> response = vinManagementClient.getVinIdsByAppUserId(
                tokenService.getLoginUserApplet().getUserId());
        List<Long> vinIds = response == null ? Collections.emptyList()
                : Optional.ofNullable(response.getData()).orElse(Collections.emptyList());
        return vinIds.contains(order.getVinId()) ? order : null;
    }
    private Long toEpochMilli(LocalDateTime time) {
        return time == null ? null : time.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }
    private Site getSite(Integer siteId) {
        if (siteId == null) {
            return null;
        }
        R<List<Site>> response = siteClient.getSiteByIds(Collections.singletonList(siteId));
        List<Site> sites = response == null ? Collections.emptyList()
                : Optional.ofNullable(response.getData()).orElse(Collections.emptyList());
        return sites.stream().findFirst().orElse(null);
    }
    private TChargingGun getGun(Integer gunId) {
        if (gunId == null) {
            return null;
        }
        R<TChargingGun> response = chargingGunClient.getChargingGunById(gunId);
        return response == null ? null : response.getData();
    }
    private void fillAppletMonitoring(Map<String, Object> result, String orderCode) {
        List<UploadRealTimeMonitoringData> dataList = orderCode == null ? Collections.emptyList()
                : monitoringDataService.getDataByOrderCode(orderCode);
        if (dataList == null || dataList.isEmpty()) {
            result.put("currentAndVoltage", Collections.emptyList());
            result.put("power", Collections.emptyList());
            return;
        }
        SimpleDateFormat formatter = new SimpleDateFormat("HH:mm");
        Map<String, UploadRealTimeMonitoringData> minuteData = new java.util.LinkedHashMap<>();
        for (UploadRealTimeMonitoringData data : dataList) {
            if (data != null && data.getCreate_time() != null) {
                minuteData.putIfAbsent(formatter.format(data.getCreate_time()), data);
            }
        }
        List<Map<String, Object>> currentAndVoltage = new ArrayList<>();
        List<Map<String, Object>> power = new ArrayList<>();
        for (Map.Entry<String, UploadRealTimeMonitoringData> entry : minuteData.entrySet()) {
            UploadRealTimeMonitoringData data = entry.getValue();
            Map<String, Object> currentItem = new HashMap<>();
            currentItem.put("time", entry.getKey());
            currentItem.put("electricity", data.getOutput_current());
            currentItem.put("voltage", data.getOutput_voltage());
            currentAndVoltage.add(currentItem);
            Map<String, Object> powerItem = new HashMap<>();
            powerItem.put("time", entry.getKey());
            powerItem.put("soc", data.getSoc());
            BigDecimal outputPower = data.getOutput_current() == null || data.getOutput_voltage() == null ? null
                    : data.getOutput_current().multiply(data.getOutput_voltage())
                    .divide(new BigDecimal("1000"), 2, RoundingMode.HALF_DOWN);
            powerItem.put("power", outputPower);
            power.add(powerItem);
        }
        result.put("currentAndVoltage", currentAndVoltage);
        result.put("power", power);
    }
    private void fillAppletExtra(List<MyVinChargingOrderList> list) {
        if (list == null || list.isEmpty()) {
            return;
ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/service/impl/TVinChargingOrderAppletServiceTest.java
@@ -7,8 +7,10 @@
import com.ruoyi.common.core.web.page.PageInfo;
import com.ruoyi.system.api.model.LoginUserApplet;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.order.api.model.TVinChargingOrder;
import com.ruoyi.order.dto.MyVinChargingOrderList;
import com.ruoyi.order.mapper.TVinChargingOrderMapper;
import com.ruoyi.order.util.mongodb.service.UploadRealTimeMonitoringDataService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -17,10 +19,13 @@
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.test.util.ReflectionTestUtils;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
@@ -42,6 +47,8 @@
    private SiteClient siteClient;
    @Mock
    private ChargingGunClient chargingGunClient;
    @Mock
    private UploadRealTimeMonitoringDataService monitoringDataService;
    @BeforeEach
    void setUp() {
@@ -82,4 +89,44 @@
        verify(mapper, never()).countAppletOrders(anyList());
        verify(mapper, never()).pageAppletOrders(anyList(), eq(0L), eq(10L));
    }
    @Test
    void returnsVinDetailWithRequiredFeeFieldsForOwner() {
        LoginUserApplet loginUser = new LoginUserApplet();
        loginUser.setUserId(88L);
        when(tokenService.getLoginUserApplet()).thenReturn(loginUser);
        when(vinManagementClient.getVinIdsByAppUserId(88L)).thenReturn(R.ok(Collections.singletonList(11L)));
        TVinChargingOrder order = new TVinChargingOrder();
        order.setId(1001L);
        order.setVinId(11L);
        order.setCode("VD_1001");
        order.setOrderAmount(new BigDecimal("18.50"));
        order.setElectrovalence(new BigDecimal("12.30"));
        order.setServiceCharge(new BigDecimal("6.20"));
        when(mapper.selectById(1001L)).thenReturn(order);
        when(mapper.accountingStrategyList(1001L)).thenReturn(Collections.emptyList());
        when(monitoringDataService.getDataByOrderCode("VD_1001")).thenReturn(Collections.emptyList());
        Map<String, Object> result = service.appletDetail(1001L);
        assertEquals("1001", result.get("id"));
        assertEquals(new BigDecimal("18.50"), result.get("orderAmount"));
        assertEquals(new BigDecimal("12.30"), result.get("electricMoney"));
        assertEquals(new BigDecimal("6.20"), result.get("serviceMoney"));
    }
    @Test
    void returnsEmptyDetailWhenVinIsNotBoundToCurrentUser() {
        LoginUserApplet loginUser = new LoginUserApplet();
        loginUser.setUserId(88L);
        when(tokenService.getLoginUserApplet()).thenReturn(loginUser);
        when(vinManagementClient.getVinIdsByAppUserId(88L)).thenReturn(R.ok(Collections.singletonList(22L)));
        TVinChargingOrder order = new TVinChargingOrder();
        order.setId(1001L);
        order.setVinId(11L);
        when(mapper.selectById(1001L)).thenReturn(order);
        assertTrue(service.appletDetail(1001L).isEmpty());
        verify(mapper, never()).accountingStrategyList(1001L);
    }
}