ソースを参照

feat(applet): 获取当前充电订单实时费用接口

- 新增 AppletChargingCostVO 用于封装充电订单实时费用信息
- AppletHomeService 接口新增 getCurrentChargingCost 方法
- AppletHomeServiceImpl 实现实时查询充电状态、终端及站点信息
- 计算并返回充电时长、电量、费用、电压电流和功率等详细数据
- AppletStationController 新增接口 /charging-cost,支持实时费用查询
- 添加接口访问限流,防止请求频率过高导致服务过载
SheepHy 1 日 前
コミット
6c98ed5682

+ 16 - 1
src/main/java/com/zsElectric/boot/business/controller/applet/AppletStationController.java

@@ -3,7 +3,9 @@ package com.zsElectric.boot.business.controller.applet;
 import com.zsElectric.boot.business.model.vo.AppletConnectorListVO;
 import com.zsElectric.boot.business.model.vo.AppletStationDetailVO;
 import com.zsElectric.boot.business.model.vo.AppletStationPriceListVO;
+import com.zsElectric.boot.business.model.vo.applet.AppletChargingCostVO;
 import com.zsElectric.boot.business.service.AppletHomeService;
+import com.zsElectric.boot.common.annotation.ApiRateLimit;
 import com.zsElectric.boot.core.web.Result;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -63,4 +65,17 @@ public class AppletStationController {
     public Result<AppletStationPriceListVO> getStationPriceList(@RequestParam Long stationId) {
         return Result.success(appletHomeService.getStationPriceList(stationId));
     }
-}
+
+    /**
+     * 获取当前充电订单实时费用
+     *
+     * @param chargeOrderNo 充电订单号
+     * @return 实时充电费用信息
+     */
+    @Operation(summary = "获取当前充电订单实时费用")
+    @GetMapping("/charging-cost")
+    @ApiRateLimit(prefix = "applet:charging_cost", limitType = ApiRateLimit.LimitType.IP, count = 2000, time = 60, message = "获取充电费用请求过于频繁,请稍后再试")
+    public Result<AppletChargingCostVO> getCurrentChargingCost(@RequestParam String chargeOrderNo) {
+        return Result.success(appletHomeService.getCurrentChargingCost(chargeOrderNo));
+    }
+}

+ 75 - 0
src/main/java/com/zsElectric/boot/business/model/vo/applet/AppletChargingCostVO.java

@@ -0,0 +1,75 @@
+package com.zsElectric.boot.business.model.vo.applet;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 小程序实时充电费用VO
+ *
+ * @author system
+ * @since 2025-12-19
+ */
+@Getter
+@Setter
+@Schema(description = "小程序实时充电费用VO")
+public class AppletChargingCostVO implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "充电订单号")
+    private String chargeOrderNo;
+
+    @Schema(description = "充电站名称")
+    private String stationName;
+
+    @Schema(description = "充电终端名称")
+    private String connectorName;
+
+    @Schema(description = "订单状态:1-启动中,2-充电中,3-停止中,4-已结束,5-未知")
+    private Integer orderStatus;
+
+    @Schema(description = "订单状态描述")
+    private String orderStatusDesc;
+
+    @Schema(description = "充电时长(秒)")
+    private Long chargingDuration;
+
+    @Schema(description = "充电时长描述(如:00:12:35)")
+    private String chargingDurationDesc;
+
+    @Schema(description = "累计充电量(度/kWh)")
+    private BigDecimal totalPower;
+
+    @Schema(description = "累计电费(元)")
+    private BigDecimal elecMoney;
+
+    @Schema(description = "累计服务费(元)")
+    private BigDecimal serviceMoney;
+
+    @Schema(description = "累计总金额(元)")
+    private BigDecimal totalMoney;
+
+    @Schema(description = "电池剩余电量SOC(%)")
+    private Integer soc;
+
+    @Schema(description = "当前电流(A)")
+    private BigDecimal current;
+
+    @Schema(description = "当前电压(V)")
+    private BigDecimal voltage;
+
+    @Schema(description = "当前功率(kW)")
+    private BigDecimal power;
+
+    @Schema(description = "充电开始时间")
+    private String startTime;
+
+    @Schema(description = "最后更新时间")
+    private String lastUpdateTime;
+}

+ 9 - 0
src/main/java/com/zsElectric/boot/business/service/AppletHomeService.java

@@ -8,6 +8,7 @@ import com.zsElectric.boot.business.model.vo.AppletStationPriceListVO;
 import com.zsElectric.boot.business.model.vo.BannerInfoVO;
 import com.zsElectric.boot.business.model.vo.StationInfoMapVO;
 import com.zsElectric.boot.business.model.vo.StationInfoVO;
+import com.zsElectric.boot.business.model.vo.applet.AppletChargingCostVO;
 
 import java.math.BigDecimal;
 import java.util.List;
@@ -52,4 +53,12 @@ public interface AppletHomeService {
      * @return 价格列表
      */
     AppletStationPriceListVO getStationPriceList(Long stationId);
+
+    /***
+     * 获取用户当前充电订单费用信息
+     * @param chargeOrderNo 充电订单号
+     * @return 实时充电费用信息
+     * */
+    AppletChargingCostVO getCurrentChargingCost(String chargeOrderNo);
+
 }

+ 124 - 0
src/main/java/com/zsElectric/boot/business/service/impl/AppletHomeServiceImpl.java

@@ -7,8 +7,10 @@ import com.zsElectric.boot.business.mapper.BannerInfoMapper;
 import com.zsElectric.boot.business.mapper.PolicyFeeMapper;
 import com.zsElectric.boot.business.mapper.ThirdPartyStationInfoMapper;
 import com.zsElectric.boot.business.mapper.UserFirmMapper;
+import com.zsElectric.boot.charging.entity.ThirdPartyChargeStatus;
 import com.zsElectric.boot.charging.entity.ThirdPartyConnectorInfo;
 import com.zsElectric.boot.charging.entity.ThirdPartyEquipmentInfo;
+import com.zsElectric.boot.charging.mapper.ThirdPartyChargeStatusMapper;
 import com.zsElectric.boot.charging.mapper.ThirdPartyConnectorInfoMapper;
 import com.zsElectric.boot.charging.entity.ThirdPartyEquipmentPricePolicy;
 import com.zsElectric.boot.charging.entity.ThirdPartyPolicyInfo;
@@ -26,6 +28,7 @@ import com.zsElectric.boot.business.model.vo.AppletStationPriceListVO;
 import com.zsElectric.boot.business.model.vo.BannerInfoVO;
 import com.zsElectric.boot.business.model.vo.StationInfoMapVO;
 import com.zsElectric.boot.business.model.vo.StationInfoVO;
+import com.zsElectric.boot.business.model.vo.applet.AppletChargingCostVO;
 import com.zsElectric.boot.business.service.AppletHomeService;
 import com.zsElectric.boot.business.converter.BannerInfoConverter;
 import com.zsElectric.boot.security.util.SecurityUtils;
@@ -56,6 +59,7 @@ public class AppletHomeServiceImpl implements AppletHomeService {
     private final ThirdPartyEquipmentPricePolicyMapper thirdPartyEquipmentPricePolicyMapper;
     private final ThirdPartyPolicyInfoMapper thirdPartyPolicyInfoMapper;
     private final PolicyFeeMapper policyFeeMapper;
+    private final ThirdPartyChargeStatusMapper thirdPartyChargeStatusMapper;
 
     /**
      * 时间格式化器 HHmmss
@@ -610,4 +614,124 @@ public class AppletHomeServiceImpl implements AppletHomeService {
         }
         return false;
     }
+
+    @Override
+    public AppletChargingCostVO getCurrentChargingCost(String chargeOrderNo) {
+        // 1. 查询充电状态记录
+        ThirdPartyChargeStatus chargeStatus = thirdPartyChargeStatusMapper.selectOne(
+                new LambdaQueryWrapper<ThirdPartyChargeStatus>()
+                        .eq(ThirdPartyChargeStatus::getStartChargeSeq, chargeOrderNo)
+                        .orderByDesc(ThirdPartyChargeStatus::getUpdateTime)
+                        .last("LIMIT 1")
+        );
+
+        if (chargeStatus == null) {
+            return null;
+        }
+
+        // 2. 通过connector_id查询充电终端信息
+        ThirdPartyConnectorInfo connectorInfo = thirdPartyConnectorInfoMapper.selectOne(
+                new LambdaQueryWrapper<ThirdPartyConnectorInfo>()
+                        .eq(ThirdPartyConnectorInfo::getConnectorId, chargeStatus.getConnectorId())
+                        .last("LIMIT 1")
+        );
+
+        if (connectorInfo == null) {
+            return null;
+        }
+
+        // 3. 通过station_id查询站点信息
+        ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectOne(
+                new LambdaQueryWrapper<ThirdPartyStationInfo>()
+                        .eq(ThirdPartyStationInfo::getStationId, connectorInfo.getStationId())
+                        .last("LIMIT 1")
+        );
+
+        // 4. 构建返回结果
+        AppletChargingCostVO result = new AppletChargingCostVO();
+        result.setChargeOrderNo(chargeOrderNo);
+        result.setStationName(stationInfo != null ? stationInfo.getStationName() : "");
+        result.setConnectorName(connectorInfo.getConnectorName());
+
+        // 订单状态
+        result.setOrderStatus(chargeStatus.getStartChargeSeqStat());
+        result.setOrderStatusDesc(getOrderStatusDesc(chargeStatus.getStartChargeSeqStat()));
+
+        // 充电时长
+        if (chargeStatus.getStartTime() != null && chargeStatus.getEndTime() != null) {
+            long duration = java.time.Duration.between(
+                    chargeStatus.getStartTime(),
+                    chargeStatus.getEndTime()
+            ).getSeconds();
+            result.setChargingDuration(duration);
+            result.setChargingDurationDesc(formatDuration(duration));
+        }
+
+        // 费用信息
+        result.setTotalPower(chargeStatus.getTotalPower() != null ? chargeStatus.getTotalPower() : BigDecimal.ZERO);
+        result.setElecMoney(chargeStatus.getElecMoney() != null ? chargeStatus.getElecMoney() : BigDecimal.ZERO);
+        result.setServiceMoney(chargeStatus.getServiceMoney() != null ? chargeStatus.getServiceMoney() : BigDecimal.ZERO);
+        result.setTotalMoney(chargeStatus.getTotalMoney() != null ? chargeStatus.getTotalMoney() : BigDecimal.ZERO);
+
+        // SOC
+        result.setSoc(chargeStatus.getSoc());
+
+        // 电压电流(取A相为主,如果没有则取其他相)
+        BigDecimal current = chargeStatus.getCurrentA() != null ? chargeStatus.getCurrentA() :
+                (chargeStatus.getCurrentB() != null ? chargeStatus.getCurrentB() : chargeStatus.getCurrentC());
+        BigDecimal voltage = chargeStatus.getVoltageA() != null ? chargeStatus.getVoltageA() :
+                (chargeStatus.getVoltageB() != null ? chargeStatus.getVoltageB() : chargeStatus.getVoltageC());
+
+        result.setCurrent(current);
+        result.setVoltage(voltage);
+
+        // 功率 = 电压 × 电流 / 1000 (kW)
+        if (current != null && voltage != null) {
+            BigDecimal power = voltage.multiply(current).divide(new BigDecimal("1000"), 2, BigDecimal.ROUND_HALF_UP);
+            result.setPower(power);
+        }
+
+        // 时间信息
+        if (chargeStatus.getStartTime() != null) {
+            result.setStartTime(chargeStatus.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        }
+        if (chargeStatus.getUpdateTime() != null) {
+            result.setLastUpdateTime(chargeStatus.getUpdateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        }
+
+        return result;
+    }
+
+    /**
+     * 获取订单状态描述
+     */
+    private String getOrderStatusDesc(Integer status) {
+        if (status == null) {
+            return "未知";
+        }
+        switch (status) {
+            case 1:
+                return "启动中";
+            case 2:
+                return "充电中";
+            case 3:
+                return "停止中";
+            case 4:
+                return "已结束";
+            case 5:
+                return "未知";
+            default:
+                return "未知";
+        }
+    }
+
+    /**
+     * 格式化时长(秒)为 HH:mm:ss
+     */
+    private String formatDuration(long seconds) {
+        long hours = seconds / 3600;
+        long minutes = (seconds % 3600) / 60;
+        long secs = seconds % 60;
+        return String.format("%02d:%02d:%02d", hours, minutes, secs);
+    }
 }