ソースを参照

feat(charging): 新增充电订单及状态相关VO类并完善推送处理逻辑

- 新增 ChargingOrderVO 类用于封装充电订单信息
- 新增 EquipChargeStatusResponseVO 类用于推送充电状态响应
- 新增 StopChargingResponseVO 类用于停止充电响应
- 删除旧的 StartChargingResponseVO 类定义
- 在 ChargingReceptionServiceImpl 中增加对充电状态、停止充电和充电订单推送的处理
- 实现数据验签验证逻辑,确保请求数据安全性
- 优化充电相关接口的响应处理流程
- 统一导入VO包路径,简化代码引用
- 增加详细的日志记录和异常处理机制
SheepHy 3 週間 前
コミット
2ff2ab1446

+ 107 - 15
src/main/java/com/zsElectric/boot/charging/service/impl/ChargingReceptionServiceImpl.java

@@ -2,10 +2,8 @@ package com.zsElectric.boot.charging.service.impl;
 
 import com.google.gson.Gson;
 import com.zsElectric.boot.charging.service.ChargingReceptionService;
-import com.zsElectric.boot.charging.vo.ChargeResponseVO;
-import com.zsElectric.boot.charging.vo.ChargingStatusResponseVO;
+import com.zsElectric.boot.charging.vo.*;
 import com.zsElectric.boot.common.constant.ConnectivityConstants;
-import com.zsElectric.boot.common.util.AESCryptoUtils;
 import com.zsElectric.boot.common.util.electric.ChargingUtil;
 import com.zsElectric.boot.common.util.electric.RequestParmsEntity;
 import com.zsElectric.boot.common.util.electric.ResponseParmsEntity;
@@ -17,6 +15,7 @@ import org.springframework.stereotype.Service;
 import static com.zsElectric.boot.common.constant.ConnectivityConstants.FAIL_REASON_NONE;
 import static com.zsElectric.boot.common.constant.ConnectivityConstants.STATUS_OK;
 import static com.zsElectric.boot.common.util.HmacMD5Util.genSign;
+import static com.zsElectric.boot.common.util.HmacMD5Util.verify;
 
 @Slf4j
 @Service
@@ -34,17 +33,22 @@ public class ChargingReceptionServiceImpl implements ChargingReceptionService {
         String encryptData;
         String genSign;
         try {
-            String decryptData = chargingUtil.decryptData(requestDTO.getData());
-            log.info("解密后的数据:{}", decryptData);
-            chargingStatusResponseVO = new Gson().fromJson(decryptData, ChargingStatusResponseVO.class);
-            //todo 业务代码待处理
+            if(verify(requestDTO.getData(), ConnectivityConstants.SIG_SECRET, requestDTO.getSig())){
+                String decryptData = chargingUtil.decryptData(requestDTO.getData());
+                log.info("解密后的数据:{}", decryptData);
+                chargingStatusResponseVO = new Gson().fromJson(decryptData, ChargingStatusResponseVO.class);
+                //todo 业务代码待处理
 
 
-            chargeResponseVO.setStartChargeSeq(chargingStatusResponseVO.getStartChargeSeq());
-            chargeResponseVO.setSuccStat(STATUS_OK);
-            chargeResponseVO.setFailReason(FAIL_REASON_NONE);
-            encryptData = chargingUtil.encryptData(new Gson().toJson(chargeResponseVO));
-            genSign = genSign(STATUS_OK, "请求成功", encryptData, ConnectivityConstants.SIG_SECRET);
+                chargeResponseVO.setStartChargeSeq(chargingStatusResponseVO.getStartChargeSeq());
+                chargeResponseVO.setSuccStat(STATUS_OK);
+                chargeResponseVO.setFailReason(FAIL_REASON_NONE);
+                encryptData = chargingUtil.encryptData(new Gson().toJson(chargeResponseVO));
+                genSign = genSign(STATUS_OK, "请求成功", encryptData, ConnectivityConstants.SIG_SECRET);
+            }else {
+                log.error("数据验签失败");
+                throw new BusinessException("数据验签失败");
+            }
         }catch (Exception e){
             log.error("数据解密失败:{}", e.getMessage());
             throw new BusinessException("数据解密失败:" + e.getMessage(), e);
@@ -59,19 +63,107 @@ public class ChargingReceptionServiceImpl implements ChargingReceptionService {
     @Override
     public ResponseParmsEntity chargeStatusResponse(RequestParmsEntity requestDTO) {
         log.info("接收推送充电状态请求参数:{}", requestDTO);
-        return null;
+        EquipChargeStatusResponseVO equipChargeStatusResponseVO;
+        ChargeResponseVO chargeResponseVO = new ChargeResponseVO();
+        String encryptData;
+        String genSign;
+        try {
+            if(verify(requestDTO.getData(), ConnectivityConstants.SIG_SECRET, requestDTO.getSig())){
+                String decryptData = chargingUtil.decryptData(requestDTO.getData());
+                log.info("解密后的数据:{}", decryptData);
+                equipChargeStatusResponseVO = new Gson().fromJson(decryptData, EquipChargeStatusResponseVO.class);
+                //todo 业务代码待处理
+
+
+
+                chargeResponseVO.setStartChargeSeq(equipChargeStatusResponseVO.getStartChargeSeq());
+                chargeResponseVO.setSuccStat(STATUS_OK);
+                chargeResponseVO.setFailReason(FAIL_REASON_NONE);
+                encryptData = chargingUtil.encryptData(new Gson().toJson(chargeResponseVO));
+                genSign = genSign(STATUS_OK, "请求成功", encryptData, ConnectivityConstants.SIG_SECRET);
+            }else {
+                log.error("数据验签失败");
+                throw new BusinessException("数据验签失败");
+            }
+        } catch (Exception e) {
+            log.error("数据解密失败:{}", e.getMessage());
+            throw new BusinessException("数据解密失败:" + e.getMessage(), e);
+        }
+        return new ResponseParmsEntity()
+                .setRet(STATUS_OK)
+                .setMsg("请求成功")
+                .setData(encryptData)
+                .setSig(genSign);
     }
 
     @Override
     public ResponseParmsEntity stopChargeResponse(RequestParmsEntity requestDTO) {
         log.info("接收推送停止充电结果请求参数:{}", requestDTO);
-        return null;
+        StopChargingResponseVO stopChargingResponseVO;
+        ChargeResponseVO chargeResponseVO = new ChargeResponseVO();
+        String encryptData;
+        String genSign;
+        try {
+            if(verify(requestDTO.getData(), ConnectivityConstants.SIG_SECRET, requestDTO.getSig())){
+                String decryptData = chargingUtil.decryptData(requestDTO.getData());
+                log.info("解密后的数据:{}", decryptData);
+                stopChargingResponseVO = new Gson().fromJson(decryptData, StopChargingResponseVO.class);
+                //todo 业务代码待处理
+
+
+                chargeResponseVO.setStartChargeSeq(stopChargingResponseVO.getStartChargeSeq());
+                chargeResponseVO.setSuccStat(STATUS_OK);
+                chargeResponseVO.setFailReason(FAIL_REASON_NONE);
+                encryptData = chargingUtil.encryptData(new Gson().toJson(chargeResponseVO));
+                genSign = genSign(STATUS_OK, "请求成功", encryptData, ConnectivityConstants.SIG_SECRET);
+            }else {
+                log.error("数据验签失败");
+                throw new BusinessException("数据验签失败");
+            }
+        } catch (Exception e) {
+            log.error("数据解密失败:{}", e.getMessage());
+            throw new BusinessException("数据解密失败:" + e.getMessage(), e);
+        }
+        return new ResponseParmsEntity()
+                .setRet(STATUS_OK)
+                .setMsg("请求成功")
+                .setData(encryptData)
+                .setSig(genSign);
     }
 
     @Override
     public ResponseParmsEntity chargeOrderResponse(RequestParmsEntity requestDTO) {
         log.info("接收推送充电订单信息请求参数:{}", requestDTO);
-        return null;
+        ChargingOrderVO chargingOrderVO;
+        ChargeResponseVO chargeResponseVO = new ChargeResponseVO();
+        String encryptData;
+        String genSign;
+        try {
+            if(verify(requestDTO.getData(), ConnectivityConstants.SIG_SECRET, requestDTO.getSig())){
+                String decryptData = chargingUtil.decryptData(requestDTO.getData());
+                log.info("解密后的数据:{}", decryptData);
+                chargingOrderVO = new Gson().fromJson(decryptData, ChargingOrderVO.class);
+                //todo 业务代码待处理
+
+
+                chargeResponseVO.setStartChargeSeq(chargingOrderVO.getStartChargeSeq());
+                chargeResponseVO.setSuccStat(STATUS_OK);
+                chargeResponseVO.setFailReason(FAIL_REASON_NONE);
+                encryptData = chargingUtil.encryptData(new Gson().toJson(chargeResponseVO));
+                genSign = genSign(STATUS_OK, "请求成功", encryptData, ConnectivityConstants.SIG_SECRET);
+            }else {
+                log.error("数据验签失败");
+                throw new BusinessException("数据验签失败");
+            }
+        } catch (Exception e) {
+            log.error("数据解密失败:{}", e.getMessage());
+            throw new BusinessException("数据解密失败:" + e.getMessage(), e);
+        }
+        return new ResponseParmsEntity()
+                .setRet(STATUS_OK)
+                .setMsg("请求成功")
+                .setData(encryptData)
+                .setSig(genSign);
     }
 
 }

+ 104 - 0
src/main/java/com/zsElectric/boot/charging/vo/ChargingOrderVO.java

@@ -0,0 +1,104 @@
+package com.zsElectric.boot.charging.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+@Accessors(chain = true)
+@Schema(description = "充电订单信息VO")
+public class ChargingOrderVO {
+
+    @Schema(description = "充电订单号(格式:运营商ID+唯一编号)",
+            example = "123456789201805071630123456",
+            required = true)
+    private String StartChargeSeq;
+
+    @Schema(description = "充电设备接口编码",
+            example = "3702120244102_1",
+            required = true)
+    private String ConnectorID;
+
+    @Schema(description = "开始充电时间,格式\"yyyy-MM-dd HH:mm:ss\"",
+            example = "2024-01-15 10:30:00",
+            required = true)
+    private String StartTime;
+
+    @Schema(description = "结束充电时间,格式\"yyyy-MM-dd HH:mm:ss\"",
+            example = "2024-01-15 12:45:30",
+            required = true)
+    private String EndTime;
+
+    @Schema(description = "累计充电量,单位:度,小数点后4位",
+            example = "25.6845",
+            required = true)
+    private BigDecimal TotalPower;
+
+    @Schema(description = "总电费,单位:元,小数点后2位",
+            example = "15.80",
+            required = true)
+    private BigDecimal TotalElecMoney;
+
+    @Schema(description = "总服务费,单位:元,小数点后2位",
+            example = "3.20",
+            required = true)
+    private BigDecimal TotalSeviceMoney;
+
+    @Schema(description = "累计总金额,单位:元,小数点后2位",
+            example = "19.00",
+            required = true)
+    private BigDecimal TotalMoney;
+
+    @Schema(description = "充电结束原因(0:用户手动停止充电;1:客户归属地运营商平台停止充电;2:BMS停止充电;3:充电机设备故障;4:连接器断开;其它:自定义)",
+            example = "0",
+            allowableValues = {"0", "1", "2", "3", "4"},
+            required = true)
+    private Integer StopReason;
+
+    @Schema(description = "时段数N,范围:0~32",
+            example = "5")
+    private Integer SumPeriod;
+
+    @Schema(description = "单时段充电明细信息")
+    private List<ChargeDetail> ChargeDetails;
+
+    @Data
+    @Accessors(chain = true)
+    @Schema(description = "充电明细信息体")
+    public static class ChargeDetail {
+
+        @Schema(description = "开始时间,格式\"yyyy-MM-dd HH:mm:ss\"",
+                example = "2024-01-15 10:30:00",
+                required = true)
+        private String DetailStartTime;
+
+        @Schema(description = "结束时间,格式\"yyyy-MM-dd HH:mm:ss\"",
+                example = "2024-01-15 11:30:00",
+                required = true)
+        private String DetailEndTime;
+
+        @Schema(description = "时段电价,小数点后2位",
+                example = "0.65")
+        private BigDecimal ElecPrice;
+
+        @Schema(description = "时段服务费价格,小数点后2位",
+                example = "0.15")
+        private BigDecimal SevicePrice;
+
+        @Schema(description = "时段充电量,单位:度,小数点后4位",
+                example = "12.3456",
+                required = true)
+        private BigDecimal DetailPower;
+
+        @Schema(description = "时段电费,小数点后2位",
+                example = "8.02")
+        private BigDecimal DetailElecMoney;
+
+        @Schema(description = "时段服务费,小数点后2位",
+                example = "1.85")
+        private BigDecimal DetailSeviceMoney;
+    }
+}

+ 76 - 0
src/main/java/com/zsElectric/boot/charging/vo/EquipChargeStatusResponseVO.java

@@ -0,0 +1,76 @@
+package com.zsElectric.boot.charging.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+@Accessors(chain = true)
+@Schema(description = "推送充电状态响应VO")
+public class EquipChargeStatusResponseVO {
+    @Schema(description = "充电订单号,27位", example = "123456789201805071630123456", required = true)
+    private String StartChargeSeq;
+
+    @Schema(description = "订单状态(1-启动中,2-启动成功,3-启动失败,4-结束)", example = "2", allowableValues = {"1", "2", "3", "4"}, required = true)
+    private Integer StartChargeSeqStat;
+
+    @Schema(description = "充电设备接口编码", example = "3702120244102_1", required = true)
+    private String ConnectorID;
+
+    @Schema(description = "设备接口状态(0-离网,1-空闲,2-占用(未充电),3-占用(充电中),4-占用(预约锁定),255-故障)", example = "3", allowableValues = {"0", "1", "2", "3", "4", "255"}, required = true)
+    private Integer ConnectorStatus;
+
+    @Schema(description = "A相电流,单位:A", example = "15.5", required = true)
+    private BigDecimal CurrentA;
+
+    @Schema(description = "A相电压,单位:V", example = "220.0", required = true)
+    private BigDecimal VoltageA;
+
+    @Schema(description = "荷电状态,0-100", example = "80", required = true)
+    private Integer Soc;
+
+    @Schema(description = "累计充电电量,单位:kWh", example = "25.68", required = true)
+    private BigDecimal TotalPower;
+
+    @Schema(description = "电费,单位:元", example = "15.80", required = true)
+    private BigDecimal ElecMoney;
+
+    @Schema(description = "服务费,单位:元", example = "3.20", required = true)
+    private BigDecimal SeviceMoney;
+
+    @Schema(description = "总金额,单位:元", example = "19.00", required = true)
+    private BigDecimal TotalMoney;
+
+    @Schema(description = "充电明细信息体列表", required = true)
+    private List<ChargeDetail> ChargeDetails;
+
+    @Data
+    @Accessors(chain = true)
+    @Schema(description = "充电明细信息体")
+    public static class ChargeDetail {
+
+        @Schema(description = "开始时间,格式\"yyyy-MM-dd HH:mm:ss\"", example = "2024-01-15 10:30:00", required = true)
+        private String DetailStartTime;
+
+        @Schema(description = "结束时间,格式\"yyyy-MM-dd HH:mm:ss\"", example = "2024-01-15 11:30:00", required = true)
+        private String DetailEndTime;
+
+        @Schema(description = "时段电价,小数点后2位", example = "0.65")
+        private BigDecimal ElecPrice;
+
+        @Schema(description = "时段服务费价格,小数点后2位", example = "0.15")
+        private BigDecimal SevicePrice;
+
+        @Schema(description = "时段充电量,单位:度,小数点后4位", example = "12.3456", required = true)
+        private BigDecimal DetailPower;
+
+        @Schema(description = "时段电费,小数点后2位", example = "8.02")
+        private BigDecimal DetailElecMoney;
+
+        @Schema(description = "时段服务费,小数点后2位", example = "1.85")
+        private BigDecimal DetailSeviceMoney;
+    }
+}

+ 7 - 8
src/main/java/com/zsElectric/boot/charging/vo/StartChargingResponseVO.java → src/main/java/com/zsElectric/boot/charging/vo/StopChargingResponseVO.java

@@ -6,8 +6,8 @@ import lombok.experimental.Accessors;
 
 @Data
 @Accessors(chain = true)
-@Schema(description = "充电启动响应VO")
-public class StartChargingResponseVO {
+@Schema(description = "停止充电响应VO")
+public class StopChargingResponseVO {
 
     @Schema(description = "充电订单号(格式:运营商ID+唯一编号)",
             example = "123456789201805071630123456",
@@ -15,7 +15,7 @@ public class StartChargingResponseVO {
     private String StartChargeSeq;
 
     @Schema(description = "充电订单状态(1-启动中,2-充电中,3-停止中,4-已结束,5-未知)",
-            example = "1",
+            example = "4",
             allowableValues = {"1", "2", "3", "4", "5"},
             required = true)
     private Integer StartChargeSeqStat;
@@ -31,14 +31,13 @@ public class StartChargingResponseVO {
             required = true)
     private Integer SuccStat;
 
-    @Schema(description = "失败原因(0-无,1-此设备不存在,2-此设备离线,其它-自定义)",
+    @Schema(description = "停止失败原因(0-无,1-此设备不存在,2-此设备离线,3-设备已停止充电,其它-自定义)",
             example = "0",
-            allowableValues = {"0", "1", "2"},
+            allowableValues = {"0", "1", "2", "3"},
             required = true)
     private Integer FailReason;
 
     @Schema(description = "失败原因描述",
-            example = "无错误",
-            required = true)
+            example = "无错误")
     private String FailReasonMsg;
-}
+}