chenxiaofei hai 5 horas
pai
achega
12e93ad045

+ 1 - 1
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/controller/ParkingChangeStrategyController.java

@@ -114,7 +114,7 @@ public class ParkingChangeStrategyController {
      * @param
      * @return
      */
-    @Operation(summary = "查询收费策略开关", description = "查询收费策略开关")
+    @Operation(summary = "开启关闭收费策略开关", description = "开启关闭收费策略开关")
     @PostMapping("/updateSwitch")
     public BaseResult updateSwitch(@RequestBody @Valid ParkingStrategySwitchSaveParam param){
         parkingChangeStrategyService.updateSwitch(param);

+ 2 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/KwtParkingStrategySwitch.java

@@ -1,5 +1,6 @@
 package com.sckw.transport.model;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 
@@ -29,6 +30,7 @@ public class KwtParkingStrategySwitch implements Serializable {
     /**
      * 默认费用
      */
+    @TableField("default_fee")
     private BigDecimal defaultFee;
 
     /**

+ 28 - 6
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/ParkingChangeStrategyService.java

@@ -27,6 +27,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
@@ -45,6 +46,8 @@ import java.util.stream.Collectors;
 public class ParkingChangeStrategyService {
 
 
+    private static final BigDecimal ZERO_AMOUNT = BigDecimal.ZERO;
+
     private final KwtParkingChangeStrategyRepository parkingChangeStrategyRepository;
     private final KwtParkingChangeStrategyUnitRepository parkingChangeStrategyUnitRepository;
     private final KwtParkingStrategySwitchRepository parkingStrategySwitchRepository;
@@ -251,22 +254,41 @@ public class ParkingChangeStrategyService {
     }
 
     /**
-     * 查询收费策略开关
+     * 修改收费策略开关
      */
     public void updateSwitch(ParkingStrategySwitchSaveParam param) {
-        log.info("修改收费策略开关");
+        log.info("修改收费策略开关,param:{}", JSON.toJSONString(param));
 
         KwtParkingStrategySwitch strategySwitch = parkingStrategySwitchRepository.getById(param.getId());
         if (strategySwitch == null) {
             throw new BusinessPlatfromException(ErrorCodeEnum.DRIVER_NOT_FOUND, "收费策略开关不存在");
         }
 
-        if (Objects.equals(param.getStatus(), Global.YES)  && param.getDefaultFee() == null) {
-            throw new BusinessPlatfromException(ErrorCodeEnum.DRIVER_NOT_FOUND, "开关打开后,默认费用不能为空");
+        if (Objects.equals(param.getStatus(), Global.YES) && param.getDefaultFee() == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "开关打开后,默认费用不能为空");
         }
-        strategySwitch.setStatus(strategySwitch.getStatus());
-        strategySwitch.setDefaultFee(strategySwitch.getDefaultFee());
+        strategySwitch.setStatus(param.getStatus());
+        strategySwitch.setDefaultFee(param.getDefaultFee());
         parkingStrategySwitchRepository.updateById(strategySwitch);
+        log.info("收费策略开关修改完成,id:{}, status:{}, defaultFee:{}",
+                strategySwitch.getId(), strategySwitch.getStatus(), strategySwitch.getDefaultFee());
+    }
+
+    /**
+     * 策略 method 为 0.00 时,展示开关表配置的默认服务费
+     */
+    private BigDecimal resolveStrategyDisplayMethod(BigDecimal method) {
+        BigDecimal actualMethod = method == null ? ZERO_AMOUNT : method;
+        if (actualMethod.compareTo(ZERO_AMOUNT) != 0) {
+            log.info("收费策略配置的计费:{}", actualMethod);
+            return actualMethod;
+        }
+        KwtParkingStrategySwitch strategySwitch = parkingStrategySwitchRepository.queryParkingStrategySwitch();
+        if (strategySwitch == null || strategySwitch.getDefaultFee() == null) {
+            log.info("收费策略未配置计费,使用默认计费:{}", ZERO_AMOUNT);
+            return ZERO_AMOUNT;
+        }
+        return strategySwitch.getDefaultFee();
     }
 
 }

+ 72 - 22
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/ParkingWalletFeeService.java

@@ -21,6 +21,7 @@ import com.sckw.transport.model.enuma.WalletTypEnum;
 import com.sckw.transport.model.param.*;
 import com.sckw.transport.repository.KwtParkingChangeStrategyRepository;
 import com.sckw.transport.repository.KwtParkingChangeStrategyUnitRepository;
+import com.sckw.transport.repository.KwtParkingStrategySwitchRepository;
 import com.sckw.transport.repository.KwtParkingWalletFeeBalanceRepository;
 import com.sckw.transport.repository.KwtParkingWalletFeeRepository;
 import lombok.RequiredArgsConstructor;
@@ -60,6 +61,7 @@ public class ParkingWalletFeeService {
     private final KwtParkingWalletFeeBalanceRepository parkingWalletFeeBalanceRepository;
     private final KwtParkingChangeStrategyRepository parkingChangeStrategyRepository;
     private final KwtParkingChangeStrategyUnitRepository parkingChangeStrategyUnitRepository;
+    private final KwtParkingStrategySwitchRepository parkingStrategySwitchRepository;
 
     @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
     RemoteSystemService remoteSystemService;
@@ -88,17 +90,17 @@ public class ParkingWalletFeeService {
 
         // 查询当前企业生效中的收费策略(仅取状态开启的最新一条)
         KwtParkingChargeStrategy currentStrategy = queryCurrentEnableStrategy(entId);
-        BigDecimal currentStrategyUnitFee = currentStrategy == null || currentStrategy.getMethod() == null
-                ? ZERO_AMOUNT : currentStrategy.getMethod();
-        log.info("服务费预估策略信息,entId:{}, strategyId:{}, strategyStatus:{}, unitFee:{}",
+        BigDecimal currentStrategyUnitFee = resolveStrategyUnitFee(currentStrategy);
+        log.info("服务费预估策略信息,entId:{}, strategyId:{}, switchOpen:{}, unitFee:{}",
                 entId,
                 currentStrategy == null ? null : currentStrategy.getId(),
-                currentStrategy == null ? null : currentStrategy.getStatus(),
+                isChargeStrategySwitchOpen(),
                 currentStrategyUnitFee);
 
         // 本次预计服务费 = 采购数量 * 策略单价,金额统一保留2位
-        BigDecimal estimatedServiceFee = param.getPurchaseQuantity().multiply(currentStrategyUnitFee)
-                .setScale(2, RoundingMode.HALF_UP);
+        BigDecimal estimatedServiceFee = isChargeStrategySwitchOpen()
+                ? param.getPurchaseQuantity().multiply(currentStrategyUnitFee).setScale(2, RoundingMode.HALF_UP)
+                : ZERO_AMOUNT;
 
         // 收费策略开关开启时,按服务费余额计算最大可购买数量
         BigDecimal maxPurchaseQuantity = calculateMaxPurchaseQuantity(currentStrategy, currentStrategyUnitFee, serviceFeeBalance);
@@ -139,14 +141,20 @@ public class ParkingWalletFeeService {
         result.setApplyChargeStrategy(Global.NO);
         result.setFreezeAmount(ZERO_AMOUNT);
 
+        if (!isChargeStrategySwitchOpen()) {
+            log.info("收费策略开关未开启,跳过服务费冻结,proEntId:{}, orderNo:{}",
+                    param.getProEntId(), param.getOrderNo());
+            return result;
+        }
+
         KwtParkingChargeStrategy currentStrategy = queryCurrentEnableStrategy(param.getProEntId());
-        if (currentStrategy == null || !Objects.equals(currentStrategy.getStatus(), STRATEGY_OPEN)) {
-            log.info("收费策略未开启或未匹配,跳过服务费冻结,proEntId:{}, orderNo:{}",
+        if (currentStrategy == null) {
+            log.info("未匹配到收费策略,跳过服务费冻结,proEntId:{}, orderNo:{}",
                     param.getProEntId(), param.getOrderNo());
             return result;
         }
 
-        BigDecimal unitFee = currentStrategy.getMethod() == null ? ZERO_AMOUNT : currentStrategy.getMethod();
+        BigDecimal unitFee = resolveStrategyUnitFee(currentStrategy);
         if (unitFee.compareTo(ZERO_AMOUNT) <= 0) {
             log.info("收费策略单价无效,跳过服务费冻结,strategyId:{}, unitFee:{}",
                     currentStrategy.getId(), unitFee);
@@ -424,16 +432,20 @@ public class ParkingWalletFeeService {
             log.info("未匹配到当前最优策略,回退使用订单关联策略,orderNo:{}, chargeStrategyId:{}",
                     param.getOrderNo(), param.getChargeStrategyId());
         }
-        if (strategy == null || strategy.getMethod() == null
-                || strategy.getMethod().compareTo(ZERO_AMOUNT) <= 0) {
+        if (strategy == null) {
             log.warn("收费策略无效,扣减金额按冻结金额处理,orderNo:{}, freezeAmount:{}", param.getOrderNo(), freezeAmount);
             return new SettleConsumeInfo(freezeAmount, transportNetWeight, null, null, null);
         }
+        BigDecimal unitFee = resolveStrategyUnitFee(strategy);
+        if (unitFee.compareTo(ZERO_AMOUNT) <= 0) {
+            log.warn("收费策略单价无效,扣减金额按冻结金额处理,orderNo:{}, freezeAmount:{}", param.getOrderNo(), freezeAmount);
+            return new SettleConsumeInfo(freezeAmount, transportNetWeight, null, null, null);
+        }
         String strategyDesc = buildStrategyMethodDesc(strategy);
-        BigDecimal consumeAmount = transportNetWeight.multiply(strategy.getMethod()).setScale(2, RoundingMode.HALF_UP);
+        BigDecimal consumeAmount = transportNetWeight.multiply(unitFee).setScale(2, RoundingMode.HALF_UP);
         log.info("按运输净重量×最优策略单价计算扣减,orderNo:{}, transportNetWeight:{}, strategyId:{}, strategyName:{}, unitFee:{}, consumeAmount:{}",
                 param.getOrderNo(), transportNetWeight, strategy.getId(), strategy.getStrategyName(),
-                strategy.getMethod(), consumeAmount);
+                unitFee, consumeAmount);
         return new SettleConsumeInfo(consumeAmount, transportNetWeight, strategy.getId(),
                 strategy.getStrategyName(), strategyDesc);
     }
@@ -566,16 +578,20 @@ public class ParkingWalletFeeService {
     }
 
     private String buildStrategyMethodDesc(KwtParkingChargeStrategy strategy) {
-        if (strategy == null || strategy.getMethod() == null) {
+        if (strategy == null) {
+            return null;
+        }
+        BigDecimal unitFee = resolveStrategyUnitFee(strategy);
+        if (unitFee.compareTo(ZERO_AMOUNT) <= 0) {
             return null;
         }
         if (Objects.equals(ParkingChangeStrategyEnum.BY_TON.getCode(), strategy.getType())) {
-            return strategy.getMethod().stripTrailingZeros().toPlainString() + "元/吨";
+            return unitFee.stripTrailingZeros().toPlainString() + "元/吨";
         }
         if (Objects.equals(ParkingChangeStrategyEnum.BY_TIME.getCode(), strategy.getType())) {
-            return strategy.getMethod().stripTrailingZeros().toPlainString() + "元/次";
+            return unitFee.stripTrailingZeros().toPlainString() + "元/次";
         }
-        return strategy.getMethod().stripTrailingZeros().toPlainString() + "元/月";
+        return unitFee.stripTrailingZeros().toPlainString() + "元/月";
     }
 
     /**
@@ -638,10 +654,11 @@ public class ParkingWalletFeeService {
     private BigDecimal calculateMaxPurchaseQuantity(KwtParkingChargeStrategy currentStrategy,
                                                     BigDecimal currentStrategyUnitFee,
                                                     BigDecimal serviceFeeBalance) {
-        if (currentStrategy == null || !Objects.equals(currentStrategy.getStatus(), STRATEGY_OPEN)
+        if (!isChargeStrategySwitchOpen() || currentStrategy == null
                 || currentStrategyUnitFee.compareTo(ZERO_AMOUNT) <= 0) {
             log.info("最大可购买数量未计算,原因:{}",
-                    currentStrategy == null ? "未匹配到收费策略" : "收费策略未开启或单价<=0");
+                    !isChargeStrategySwitchOpen() ? "收费策略开关未开启"
+                            : currentStrategy == null ? "未匹配到收费策略" : "策略单价<=0");
             return null;
         }
         //向下取整
@@ -651,6 +668,39 @@ public class ParkingWalletFeeService {
         return maxPurchaseQuantity.max(ZERO_AMOUNT);
     }
 
+    /**
+     * 判断收费策略总开关是否开启(以 kwt_parking_strategy_switch 表为准)
+     */
+    private boolean isChargeStrategySwitchOpen() {
+        KwtParkingStrategySwitch strategySwitch = parkingStrategySwitchRepository.queryParkingStrategySwitch();
+        return strategySwitch != null && Objects.equals(strategySwitch.getStatus(), STRATEGY_OPEN);
+    }
+
+    /**
+     * 查询收费策略开关配置的默认服务费
+     */
+    private BigDecimal resolveDefaultFee() {
+        KwtParkingStrategySwitch strategySwitch = parkingStrategySwitchRepository.queryParkingStrategySwitch();
+        if (strategySwitch == null || strategySwitch.getDefaultFee() == null) {
+            return ZERO_AMOUNT;
+        }
+        return strategySwitch.getDefaultFee();
+    }
+
+    /**
+     * 解析策略实际计费单价:method 为 0.00 时使用开关表 default_fee
+     */
+    private BigDecimal resolveStrategyUnitFee(KwtParkingChargeStrategy strategy) {
+        if (strategy == null) {
+            return ZERO_AMOUNT;
+        }
+        BigDecimal method = strategy.getMethod() == null ? ZERO_AMOUNT : strategy.getMethod();
+        if (method.compareTo(ZERO_AMOUNT) == 0) {
+            return resolveDefaultFee();
+        }
+        return method;
+    }
+
     /**
      * 查询企业当前生效的收费策略(开启状态中 id 最大的一条,用于下单冻结/预估)
      *
@@ -674,14 +724,14 @@ public class ParkingWalletFeeService {
      */
     private KwtParkingChargeStrategy queryOptimalEnableStrategy(Long proEntId) {
         KwtParkingChargeStrategy optimalStrategy = listEnableStrategiesByProEntId(proEntId).stream()
-                .filter(item -> item.getMethod() != null && item.getMethod().compareTo(ZERO_AMOUNT) > 0)
-                .min(Comparator.comparing(KwtParkingChargeStrategy::getMethod)
+                .filter(item -> resolveStrategyUnitFee(item).compareTo(ZERO_AMOUNT) > 0)
+                .min(Comparator.comparing(this::resolveStrategyUnitFee)
                         .thenComparing(Comparator.comparing(KwtParkingChargeStrategy::getId).reversed()))
                 .orElse(null);
         log.info("匹配最优收费策略结果,proEntId:{}, optimalStrategyId:{}, unitFee:{}",
                 proEntId,
                 optimalStrategy == null ? null : optimalStrategy.getId(),
-                optimalStrategy == null ? null : optimalStrategy.getMethod());
+                optimalStrategy == null ? null : resolveStrategyUnitFee(optimalStrategy));
         return optimalStrategy;
     }
 

+ 3 - 0
sql/2026/06/2026_06_26_init_parking_strategy_switch.sql

@@ -0,0 +1,3 @@
+INSERT INTO kwt_parking_strategy_switch (status, default_fee, create_user, update_user)
+SELECT 0, 0.00, -1, -1
+WHERE NOT EXISTS (SELECT 1 FROM kwt_parking_strategy_switch LIMIT 1);