Forráskód Böngészése

feat(charging): 优化充电订单推送及结算逻辑

- chargeOrderResponse方法添加异常抛出声明,增强异常处理能力
- 实现推送的充电订单信息处理,完善订单字段赋值和状态更新
- 依据充电明细计算平台服务费并更新订单
- 调用orderSettlement方法完成账户余额扣减及积分添加
- orderSettlement中从订单信息获取用户ID,累加积分到账户
- 新增DateUtils.getDuration方法,支持多格式解析日期计算充电时长(秒)
wzq 1 napja
szülő
commit
f597f9f510

+ 8 - 1
src/main/java/com/zsElectric/boot/business/service/impl/ChargeOrderInfoServiceImpl.java

@@ -275,12 +275,19 @@ public class ChargeOrderInfoServiceImpl extends ServiceImpl<ChargeOrderInfoMappe
 
     @Override
     public void orderSettlement(Long chargeOrderId) {
-        Long userId = SecurityUtils.getUserId();
+
         ChargeOrderInfo chargeOrderInfo = this.getById(chargeOrderId);
+        Long userId = chargeOrderInfo.getUserId();
 
         //平台收费总金额
         BigDecimal totalCharge = chargeOrderInfo.getRealCost();
 
+        //加积分
+        userAccountService.update(Wrappers.lambdaUpdate(UserAccount.class)
+                .eq(UserAccount::getUserId, userId)
+                .setSql("`integral` = `integral` +" + totalCharge)
+        );
+
         //账户变动及日志记录
         userAccountService.updateAccountBalanceAndLog(
                 userId,

+ 1 - 1
src/main/java/com/zsElectric/boot/charging/service/ChargingReceptionService.java

@@ -30,7 +30,7 @@ public interface ChargingReceptionService {
     /**
      * 2.9 推送充电订单信息
      * */
-    ResponseParmsEntity chargeOrderResponse(RequestParmsEntity requestDTO);
+    ResponseParmsEntity chargeOrderResponse(RequestParmsEntity requestDTO) throws Exception;
 
     /**
      * 3.2 设备状态变化推送

+ 61 - 9
src/main/java/com/zsElectric/boot/charging/service/impl/ChargingReceptionServiceImpl.java

@@ -22,6 +22,7 @@ import com.zsElectric.boot.charging.vo.ChargeResponseVO;
 import com.zsElectric.boot.charging.vo.QueryStationStatusVO;
 import com.zsElectric.boot.common.constant.ConnectivityConstants;
 import com.zsElectric.boot.common.constant.SystemConstants;
+import com.zsElectric.boot.common.util.DateUtils;
 import com.zsElectric.boot.common.util.electric.ChargingUtil;
 import com.zsElectric.boot.common.util.electric.RequestParmsEntity;
 import com.zsElectric.boot.common.util.electric.ResponseParmsEntity;
@@ -36,6 +37,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.HashMap;
@@ -183,18 +185,12 @@ public class ChargingReceptionServiceImpl implements ChargingReceptionService {
         });
     }
 
+
+
     @Override
-    public ResponseParmsEntity chargeOrderResponse(RequestParmsEntity requestDTO) {
+    public ResponseParmsEntity chargeOrderResponse(RequestParmsEntity requestDTO) throws Exception {
         log.info("接收推送充电订单信息请求参数:{}", requestDTO);
         return processChargeRequest(requestDTO, jsonNode -> {
-            // 充电订单信息业务处理
-            //订单结算:平台实际收取金额 = 互联互通金额 + 中数电动金额(平台总服务费)
-
-
-
-
-            //账户余额扣减
-//            chargeOrderInfoService.orderSettlement();
             log.debug("充电订单信息 - StartChargeSeq: {}", getTextValue(jsonNode, "StartChargeSeq"));
         });
     }
@@ -214,6 +210,62 @@ public class ChargingReceptionServiceImpl implements ChargingReceptionService {
         try {
             JsonNode jsonNode = verifyAndDecrypt(requestDTO);
 
+            //查询订单
+            String startChargeSeq = getTextValue(jsonNode, "StartChargeSeq");
+            String stopReason = getTextValue(jsonNode, "StopReason");
+            String endTime = getTextValue(jsonNode, "EndTime");
+            String totalPower = getTextValue(jsonNode, "TotalPower");
+            String totalElecMoney = getTextValue(jsonNode, "TotalElecMoney");
+            String totalMoney = getTextValue(jsonNode, "TotalMoney");
+            String totalSeviceMoney = getTextValue(jsonNode, "TotalSeviceMoney");
+            String connectorID = getTextValue(jsonNode, "ConnectorID");
+
+            ChargeOrderInfo chargeOrderInfo = chargeOrderInfoService.getOne(new LambdaQueryWrapper<ChargeOrderInfo>()
+                    .eq(ChargeOrderInfo::getStartChargeSeq, startChargeSeq).last("LIMIT 1"));
+
+            chargeOrderInfo.setStopReason(stopReason);
+            chargeOrderInfo.setEndTime(endTime);
+            chargeOrderInfo.setTotalCharge(new BigDecimal(totalPower));
+
+            chargeOrderInfo.setThirdPartyTotalCost(new BigDecimal(totalMoney));
+            chargeOrderInfo.setThirdPartyServerfee(new  BigDecimal(totalSeviceMoney));
+            chargeOrderInfo.setThirdPartyElecfee(new BigDecimal(totalElecMoney));
+
+            ThirdPartyConnectorInfo thirdPartyConnectorInfo = connectorInfoMapper.selectOne(Wrappers.<ThirdPartyConnectorInfo>lambdaQuery()
+                    .eq(ThirdPartyConnectorInfo::getConnectorId, connectorID).last("LIMIT 1"));
+            String stationId = thirdPartyConnectorInfo.getStationId();
+
+            //平台服务费
+            BigDecimal serviceFee = BigDecimal.ZERO;
+            JsonNode chargeDetails = jsonNode.get("ChargeDetails");
+            for (JsonNode node : chargeDetails) {
+                //提取字段值
+                String itemFlag = node.get("ItemFlag").asText();
+                double detailPower = node.get("DetailPower").asDouble();
+                PolicyFee policyFee = policyFeeMapper.selectOne(Wrappers.<PolicyFee>lambdaQuery()
+                        .eq(PolicyFee::getStationInfoId, stationId)
+                        .eq(PolicyFee::getPeriodFlag, Integer.parseInt(itemFlag))
+                        .last("LIMIT 1"));
+                BigDecimal opFee = policyFee.getOpFee();
+                serviceFee = serviceFee.add(opFee.multiply(new BigDecimal(detailPower))).setScale(2, RoundingMode.HALF_UP);
+            }
+
+            chargeOrderInfo.setRealServiceCost(serviceFee);
+            //订单结算:平台实际收取金额 = 互联互通金额 + 中数电动金额(平台总服务费)
+            chargeOrderInfo.setRealCost(chargeOrderInfo.getRealServiceCost().add(chargeOrderInfo.getThirdPartyTotalCost()));
+
+            //订单状态->已完成
+            chargeOrderInfo.setStatus(SystemConstants.STATUS_THREE);
+
+            //计算充电时间
+            chargeOrderInfo.setChargeTime(DateUtils.getDuration(chargeOrderInfo.getStartTime(), chargeOrderInfo.getEndTime()));
+
+            //修改订单
+            chargeOrderInfoService.updateById(chargeOrderInfo);
+
+            //账户余额扣减(积分增加)
+            chargeOrderInfoService.orderSettlement(chargeOrderInfo.getId());
+
             // 执行业务处理
             businessHandler.accept(jsonNode);
 

+ 59 - 0
src/main/java/com/zsElectric/boot/common/util/DateUtils.java

@@ -8,6 +8,9 @@ import cn.hutool.core.util.StrUtil;
 import org.springframework.format.annotation.DateTimeFormat;
 
 import java.lang.reflect.Field;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
 
 /**
  * 日期工具类
@@ -58,4 +61,60 @@ public class DateUtils {
             ReflectUtil.setFieldValue(obj, fieldName, dateTime.toString(targetPattern));
         }
     }
+
+    /**
+     * 计算两个时间之间的持续时间(秒)
+     * 支持多种常见的日期时间格式
+     *
+     * @param startTime 开始时间字符串
+     * @param endTime   结束时间字符串
+     * @return 持续时间(秒),如果任一参数为空则返回0
+     */
+    public static Integer getDuration(String startTime, String endTime) {
+        if (StrUtil.isBlank(startTime) || StrUtil.isBlank(endTime)) {
+            return 0;
+        }
+
+        try {
+            // 定义支持的日期时间格式
+            DateTimeFormatter[] formatters = {
+                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
+                    DateTimeFormatter.ofPattern("yyyyMMddHHmmss"),
+                    DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"),
+                    DateTimeFormatter.ISO_LOCAL_DATE_TIME
+            };
+
+            LocalDateTime start = parseDateTime(startTime, formatters);
+            LocalDateTime end = parseDateTime(endTime, formatters);
+
+            if (start == null || end == null) {
+                return 0;
+            }
+
+            // 计算秒数差
+            long seconds = ChronoUnit.SECONDS.between(start, end);
+            return (int) seconds;
+        } catch (Exception e) {
+            // 解析失败,返回0
+            return 0;
+        }
+    }
+
+    /**
+     * 尝试使用多种格式解析时间字符串
+     *
+     * @param dateTimeStr 时间字符串
+     * @param formatters  格式化器数组
+     * @return 解析后的LocalDateTime对象,解析失败返回null
+     */
+    private static LocalDateTime parseDateTime(String dateTimeStr, DateTimeFormatter[] formatters) {
+        for (DateTimeFormatter formatter : formatters) {
+            try {
+                return LocalDateTime.parse(dateTimeStr, formatter);
+            } catch (Exception ignored) {
+                // 尝试下一个格式
+            }
+        }
+        return null;
+    }
 }