chenxiaofei vor 5 Stunden
Ursprung
Commit
4341b3a7e3
26 geänderte Dateien mit 1604 neuen und 0 gelöschten Zeilen
  1. 51 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/model/enums/ParkingChangeStrategyEnum.java
  2. 101 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/controller/ParkingChangeStrategyController.java
  3. 101 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/controller/ParkingWalletFeeController.java
  4. 35 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/controller/ParkingWalletFeeEstimateController.java
  5. 16 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/dao/KwtParkingChangeStrategyMapper.java
  6. 16 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/dao/KwtParkingChangeStrategyUnitMapper.java
  7. 16 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/dao/KwtParkingWalletFeeBalanceMapper.java
  8. 17 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/dao/KwtParkingWalletFeeMapper.java
  9. 73 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/KwtParkingChargeStrategy.java
  10. 57 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/KwtParkingChargeStrategyUnit.java
  11. 73 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/KwtParkingWalletFee.java
  12. 83 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/KwtParkingWalletFeeBalance.java
  13. 65 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/ParkingChangeStrategySaveParam.java
  14. 49 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/ParkingChangeStrategyQueryParam.java
  15. 92 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/ParkingChangeStrategyResp.java
  16. 40 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/ParkingChangeStrategyUnitResp.java
  17. 37 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/ParkingChangeStrategyUnitSaveParam.java
  18. 25 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/ParkingWalletFeeEstimateQueryParam.java
  19. 36 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/ParkingWalletFeeEstimateResp.java
  20. 28 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtParkingChangeStrategyRepository.java
  21. 35 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtParkingChangeStrategyUnitRepository.java
  22. 31 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtParkingWalletFeeBalanceRepository.java
  23. 28 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtParkingWalletFeeRepository.java
  24. 233 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/ParkingChangeStrategyService.java
  25. 202 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/ParkingWalletFeeService.java
  26. 64 0
      sql/2026/06/2026_06_16_create.sql

+ 51 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/model/enums/ParkingChangeStrategyEnum.java

@@ -0,0 +1,51 @@
+package com.sckw.core.model.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.EnumSet;
+
+/**
+ * @author lfdc
+ * @desc 收费策略类型
+ * @date 2023-07-14 14:07:23
+ */
+@Getter
+@AllArgsConstructor
+public enum ParkingChangeStrategyEnum {
+
+    /**
+     * 按吨计费
+     */
+    BY_TON(1, "按吨计费"),
+
+    /**
+     * 按次计费
+     */
+    BY_TIME(2, "按次计费"),
+
+    /**
+     * 按月计费
+     */
+    BY_MONTH(3, "按月计费");
+
+    ;
+
+    private final Integer code;
+
+    private final String desc;
+
+
+    public static String geDesc(Integer status) {
+        if (status == null) {
+            return null;
+        }
+        for (ParkingChangeStrategyEnum carWaybillV1Enum : EnumSet.allOf(ParkingChangeStrategyEnum.class)) {
+            if (carWaybillV1Enum.code.equals(status)) {
+                return carWaybillV1Enum.desc;
+            }
+        }
+        return null;
+    }
+
+}

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

@@ -0,0 +1,101 @@
+package com.sckw.transport.controller;
+
+
+import com.sckw.core.web.response.BaseResult;
+import com.sckw.core.web.response.result.PageDataResult;
+import com.sckw.transport.model.ParkingChangeStrategySaveParam;
+import com.sckw.transport.model.param.ParkingChangeStrategyQueryParam;
+import com.sckw.transport.model.param.ParkingChangeStrategyResp;
+import com.sckw.transport.model.param.ParkingChangeStrategyUnitResp;
+import com.sckw.transport.model.param.ParkingChangeStrategyUnitSaveParam;
+import com.sckw.transport.service.ParkingChangeStrategyService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * Author: donglang
+ * Time: 2026-01-05
+ * Des: 收费策略Controller
+ * Version: 1.0
+ */
+
+@RestController
+@RequestMapping("/strategy")
+@RequiredArgsConstructor
+@Tag(name = "收费策略接口", description = "收费策略接口")
+public class ParkingChangeStrategyController {
+
+    private final ParkingChangeStrategyService parkingChangeStrategyService;
+
+    /**
+     * 分页查询门卫订单
+     *
+     * @param param
+     * @return
+     */
+    @Operation(summary = "分页查询收费策略", description = "分页查询收费策略")
+    @PostMapping("/pageQueryChangeStrategy")
+    public BaseResult<PageDataResult<ParkingChangeStrategyResp>> pageQueryChangeStrategy(@RequestBody @Valid ParkingChangeStrategyQueryParam param){
+        PageDataResult<ParkingChangeStrategyResp> gatekeeperOrderList = parkingChangeStrategyService.pageQueryChangeStrategy(param);
+        return BaseResult.success(gatekeeperOrderList);
+    }
+
+    /**
+     * 保存收费策略
+     *
+     * @param param
+     * @return
+     */
+    @Operation(summary = "保存收费策略", description = "保存收费策略")
+    @PostMapping("/saveChangeStrategy")
+    public BaseResult saveChangeStrategy(@RequestBody @Valid ParkingChangeStrategySaveParam param){
+        parkingChangeStrategyService.saveChangeStrategy(param);
+        return BaseResult.success();
+    }
+
+    /**
+     * 删除收费策略
+     *
+     * @param id
+     * @return
+     */
+    @Operation(summary = "删除收费策略", description = "删除收费策略")
+    @PostMapping("/deleteChangeStrategy")
+    public BaseResult deleteChangeStrategy(@RequestParam Long id){
+        parkingChangeStrategyService.deleteChangeStrategy(id);
+        return BaseResult.success();
+    }
+
+    /**
+     * 查询单位分配
+     *
+     * @param id
+     * @return
+     */
+    @Operation(summary = "查询单位分配", description = "查询单位分配")
+    @PostMapping("/queryChangeStrategyEnt")
+    public BaseResult<List<ParkingChangeStrategyUnitResp>> queryChangeStrategyEnt(@RequestParam Long id){
+        List<ParkingChangeStrategyUnitResp> changeStrategyUnitRespList = parkingChangeStrategyService.queryChangeStrategyEnt(id);
+        return BaseResult.success(changeStrategyUnitRespList);
+    }
+
+    /**
+     * 保存单位分配
+     *
+     * @param param
+     * @return
+     */
+    @Operation(summary = "保存单位分配", description = "保存单位分配")
+    @PostMapping("/saveChangeStrategyEnt")
+    public BaseResult saveChangeStrategyEnt(@RequestBody @Valid ParkingChangeStrategyUnitSaveParam param){
+        parkingChangeStrategyService.saveChangeStrategyEnt(param);
+        return BaseResult.success();
+    }
+
+
+}

+ 101 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/controller/ParkingWalletFeeController.java

@@ -0,0 +1,101 @@
+package com.sckw.transport.controller;
+
+
+import com.sckw.core.web.response.BaseResult;
+import com.sckw.core.web.response.result.PageDataResult;
+import com.sckw.transport.model.ParkingChangeStrategySaveParam;
+import com.sckw.transport.model.param.ParkingChangeStrategyQueryParam;
+import com.sckw.transport.model.param.ParkingChangeStrategyResp;
+import com.sckw.transport.model.param.ParkingChangeStrategyUnitResp;
+import com.sckw.transport.model.param.ParkingChangeStrategyUnitSaveParam;
+import com.sckw.transport.service.ParkingChangeStrategyService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * Author: donglang
+ * Time: 2026-01-05
+ * Des: 服务费
+ * Version: 1.0
+ */
+
+@RestController
+@RequestMapping("/parking/wallet")
+@RequiredArgsConstructor
+@Tag(name = "服务费接口", description = "服务费接口")
+public class ParkingWalletFeeController {
+
+    private final ParkingChangeStrategyService parkingChangeStrategyService;
+
+    /**
+     * 分页查询门卫订单
+     *
+     * @param param
+     * @return
+     */
+    @Operation(summary = "分页查询收费策略", description = "分页查询收费策略")
+    @PostMapping("/pageQueryChangeStrategy")
+    public BaseResult<PageDataResult<ParkingChangeStrategyResp>> pageQueryChangeStrategy(@RequestBody @Valid ParkingChangeStrategyQueryParam param){
+        PageDataResult<ParkingChangeStrategyResp> gatekeeperOrderList = parkingChangeStrategyService.pageQueryChangeStrategy(param);
+        return BaseResult.success(gatekeeperOrderList);
+    }
+
+    /**
+     * 保存收费策略
+     *
+     * @param param
+     * @return
+     */
+    @Operation(summary = "保存收费策略", description = "保存收费策略")
+    @PostMapping("/saveChangeStrategy")
+    public BaseResult saveChangeStrategy(@RequestBody @Valid ParkingChangeStrategySaveParam param){
+        parkingChangeStrategyService.saveChangeStrategy(param);
+        return BaseResult.success();
+    }
+
+    /**
+     * 删除收费策略
+     *
+     * @param id
+     * @return
+     */
+    @Operation(summary = "删除收费策略", description = "删除收费策略")
+    @PostMapping("/deleteChangeStrategy")
+    public BaseResult deleteChangeStrategy(@RequestParam Long id){
+        parkingChangeStrategyService.deleteChangeStrategy(id);
+        return BaseResult.success();
+    }
+
+    /**
+     * 查询单位分配
+     *
+     * @param id
+     * @return
+     */
+    @Operation(summary = "查询单位分配", description = "查询单位分配")
+    @PostMapping("/queryChangeStrategyEnt")
+    public BaseResult<List<ParkingChangeStrategyUnitResp>> queryChangeStrategyEnt(@RequestParam Long id){
+        List<ParkingChangeStrategyUnitResp> changeStrategyUnitRespList = parkingChangeStrategyService.queryChangeStrategyEnt(id);
+        return BaseResult.success(changeStrategyUnitRespList);
+    }
+
+    /**
+     * 保存单位分配
+     *
+     * @param param
+     * @return
+     */
+    @Operation(summary = "保存单位分配", description = "保存单位分配")
+    @PostMapping("/saveChangeStrategyEnt")
+    public BaseResult saveChangeStrategyEnt(@RequestBody @Valid ParkingChangeStrategyUnitSaveParam param){
+        parkingChangeStrategyService.saveChangeStrategyEnt(param);
+        return BaseResult.success();
+    }
+
+
+}

+ 35 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/controller/ParkingWalletFeeEstimateController.java

@@ -0,0 +1,35 @@
+package com.sckw.transport.controller;
+
+import com.sckw.core.web.response.BaseResult;
+import com.sckw.transport.model.param.ParkingWalletFeeEstimateQueryParam;
+import com.sckw.transport.model.param.ParkingWalletFeeEstimateResp;
+import com.sckw.transport.service.ParkingWalletFeeService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Author: donglang
+ * Time: 2026-06-25
+ * Des: 服务费预估
+ * Version: 1.0
+ */
+@RestController
+@RequestMapping("/parking/wallet/fee")
+@RequiredArgsConstructor
+@Tag(name = "服务费预估接口", description = "服务费预估接口")
+public class ParkingWalletFeeEstimateController {
+
+    private final ParkingWalletFeeService parkingWalletFeeService;
+
+    @Operation(summary = "查询服务费余额、本次预计服务费与最大可购买数量", description = "查询服务费余额、本次预计服务费与最大可购买数量")
+    @PostMapping("/queryEstimate")
+    public BaseResult<ParkingWalletFeeEstimateResp> queryEstimate(@RequestBody @Valid ParkingWalletFeeEstimateQueryParam param) {
+        return BaseResult.success(parkingWalletFeeService.queryEstimateServiceFee(param));
+    }
+}

+ 16 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/dao/KwtParkingChangeStrategyMapper.java

@@ -0,0 +1,16 @@
+package com.sckw.transport.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sckw.transport.model.KwtParkingChargeStrategy;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author zk
+ * @desc 门卫车辆订单
+ * @date 2026/01/06
+ */
+@Mapper
+public interface KwtParkingChangeStrategyMapper extends BaseMapper<KwtParkingChargeStrategy> {
+
+
+}

+ 16 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/dao/KwtParkingChangeStrategyUnitMapper.java

@@ -0,0 +1,16 @@
+package com.sckw.transport.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sckw.transport.model.KwtParkingChargeStrategyUnit;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author zk
+ * @desc 门卫车辆订单
+ * @date 2026/01/06
+ */
+@Mapper
+public interface KwtParkingChangeStrategyUnitMapper extends BaseMapper<KwtParkingChargeStrategyUnit> {
+
+
+}

+ 16 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/dao/KwtParkingWalletFeeBalanceMapper.java

@@ -0,0 +1,16 @@
+package com.sckw.transport.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sckw.transport.model.KwtParkingWalletFeeBalance;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author zk
+ * @desc 门卫车辆订单
+ * @date 2026/01/06
+ */
+@Mapper
+public interface KwtParkingWalletFeeBalanceMapper extends BaseMapper<KwtParkingWalletFeeBalance> {
+
+
+}

+ 17 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/dao/KwtParkingWalletFeeMapper.java

@@ -0,0 +1,17 @@
+package com.sckw.transport.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sckw.transport.model.KwtParkingChargeStrategy;
+import com.sckw.transport.model.KwtParkingWalletFee;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author zk
+ * @desc 门卫车辆订单
+ * @date 2026/01/06
+ */
+@Mapper
+public interface KwtParkingWalletFeeMapper extends BaseMapper<KwtParkingWalletFee> {
+
+
+}

+ 73 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/KwtParkingChargeStrategy.java

@@ -0,0 +1,73 @@
+package com.sckw.transport.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * @author lfdc
+ * @description 收费策略
+ * @date 2023-06-26 16:06:12
+ */
+@Data
+@TableName("kwt_parking_charge_strategy")
+public class KwtParkingChargeStrategy implements Serializable {
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 策略名称
+     */
+    private String strategyName;
+
+    /**
+     * 策略类型(1-按吨计费,2-按次计费、3-按月计费)
+     */
+    private Integer type;
+
+    /**
+     * 计价方式
+     */
+    private BigDecimal method;
+
+    /**
+     * 状态(0-关闭,1-开启)
+     */
+    private Integer status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 创建人
+     */
+    private Long createBy;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 创建人更新人
+     */
+    private Long updateBy;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * 是否删除(0未删除,1删除)
+     */
+    private Integer delFlag;
+}

+ 57 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/KwtParkingChargeStrategyUnit.java

@@ -0,0 +1,57 @@
+package com.sckw.transport.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @author lfdc
+ * @description 收费策略
+ * @date 2023-06-26 16:06:12
+ */
+@Data
+@TableName("kwt_parking_charge_strategy_unit")
+public class KwtParkingChargeStrategyUnit implements Serializable {
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 策略id
+     */
+    private Long strategyId;
+
+    /**
+     * 企业id
+     */
+    private Long entId;
+
+    /**
+     * 创建人
+     */
+    private Long createBy;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 创建人更新人
+     */
+    private Long updateBy;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * 是否删除(0未删除,1删除)
+     */
+    private Integer delFlag;
+}

+ 73 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/KwtParkingWalletFee.java

@@ -0,0 +1,73 @@
+package com.sckw.transport.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * @author lfdc
+ * @description 服务费
+ * @date 2023-06-26 16:06:12
+ */
+@Data
+@TableName("kwt_parking_wallet_fee")
+public class KwtParkingWalletFee implements Serializable {
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 采购商企业id
+     */
+    private Long proEntId;
+
+    /**
+     * 服务费余额
+     */
+    private BigDecimal serviceFeeBalance;
+
+    /**
+     * 履约中金额
+     */
+    private BigDecimal tradingAmount;
+
+    /**
+     * 凭证图片
+     */
+    private String voucherUrl;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 创建人
+     */
+    private Long createBy;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 创建人更新人
+     */
+    private Long updateBy;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * 是否删除(0未删除,1删除)
+     */
+    private Integer delFlag;
+}

+ 83 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/KwtParkingWalletFeeBalance.java

@@ -0,0 +1,83 @@
+package com.sckw.transport.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * @author lfdc
+ * @description 服务费明细
+ * @date 2023-06-26 16:06:12
+ */
+@Data
+@TableName("kwt_parking_wallet_fee_balance")
+public class KwtParkingWalletFeeBalance implements Serializable {
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 关联订单编号
+     */
+    private String orderNo;
+
+    /**
+     * 采购商企业id
+     */
+    private Long proEntId;
+
+    /**
+     * 交易类型 2-预付 3-收益 4-冻结 5-解冻 6-消费 9-人工录入
+     */
+    private Integer tradeType;
+
+    /**
+     * 交易金额
+     */
+    private BigDecimal tradeAmount;
+
+    /**
+     * 服务费余额
+     */
+    private BigDecimal serviceFeeBalance;
+
+    /**
+     * 履约中金额
+     */
+    private BigDecimal tradingAmount;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 创建人
+     */
+    private Long createBy;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 创建人更新人
+     */
+    private Long updateBy;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * 是否删除(0未删除,1删除)
+     */
+    private Integer delFlag;
+}

+ 65 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/ParkingChangeStrategySaveParam.java

@@ -0,0 +1,65 @@
+package com.sckw.transport.model;
+
+import com.sckw.core.web.request.PageReq;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * @author :donglang
+ * @version :1.0
+ * @description : 收费策略
+ * @create :2026-01-05 08:59:00
+ */
+@Data
+public class ParkingChangeStrategySaveParam extends PageReq implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = -5431003248533000828L;
+
+    /**
+     * 主键id
+     */
+    @Schema(description = "主键id")
+    private Long id;
+
+    /**
+     * 策略名称
+     */
+    @NotBlank(message = "策略名称不能为空")
+    @Schema(description = "策略名称")
+    private String strategyName;
+
+    /**
+     * 策略类型(1-按吨计费,2-按次计费、3-按月计费)
+     */
+    @NotNull(message = "策略类型不能为空")
+    @Schema(description = "策略类型")
+    private Integer type;
+
+    /**
+     * 计价方式
+     */
+    @NotNull(message = "计价方式不能为空")
+    @Schema(description = "计价方式")
+    private BigDecimal method;
+
+    /**
+     * 状态(0-关闭,1-开启)
+     */
+    @Schema(description = "状态")
+    private Integer status;
+
+    /**
+     * 备注
+     */
+    @Schema(description = "计价方式")
+    private String remark;
+
+
+}

+ 49 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/ParkingChangeStrategyQueryParam.java

@@ -0,0 +1,49 @@
+package com.sckw.transport.model.param;
+
+import com.sckw.core.web.request.PageReq;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * @author :donglang
+ * @version :1.0
+ * @description : 收费策略
+ * @create :2026-01-05 08:59:00
+ */
+@Data
+public class ParkingChangeStrategyQueryParam extends PageReq implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = -5431003248533000828L;
+
+    /**
+     * 平台企业id
+     */
+    @NotNull(message = "平台企业id不能为空")
+    @Schema(description = "平台企业id")
+    private Long entId;
+
+    /**
+     * 策略名称
+     */
+    @Schema(description = "策略名称")
+    private String strategyName;
+
+    /**
+     * 策略类型(1-按吨计费,2-按次计费、3-按月计费)
+     */
+    @Schema(description = "策略类型")
+    private Integer type;
+
+    /**
+     * 单位名称
+     */
+    @Schema(description = "单位名称")
+    private String entName;
+
+
+}

+ 92 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/ParkingChangeStrategyResp.java

@@ -0,0 +1,92 @@
+package com.sckw.transport.model.param;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * @author :chenXiaoFei
+ * @version :1.0
+ * @description : 分页查询收费策略
+ * @create :2025-11-11 20:16:00
+ */
+@Data
+public class ParkingChangeStrategyResp implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = -6153312023002477484L;
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 策略名称
+     */
+    private String strategyName;
+
+    /**
+     * 策略类型(1-按吨计费,2-按次计费、3-按月计费)
+     */
+    private Integer type;
+
+    /**
+     * 策略类型描述
+     */
+    private String typeDesc;
+
+    /**
+     * 计价方式
+     */
+    private BigDecimal method;
+
+    /**
+     * 计价方式
+     */
+    private String methodDesc;
+
+    /**
+     * 	使用单位数
+     */
+    private Integer EntNumber;
+
+    /**
+     * 状态(0-关闭,1-开启)
+     */
+    private Integer status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 创建人
+     */
+    private Long createBy;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 创建人更新人
+     */
+    private Long updateBy;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * 是否删除(0未删除,1删除)
+     */
+    private Integer delFlag;
+
+}

+ 40 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/ParkingChangeStrategyUnitResp.java

@@ -0,0 +1,40 @@
+package com.sckw.transport.model.param;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * @author :chenXiaoFei
+ * @version :1.0
+ * @description : 查询收费策略分配单位
+ * @create :2025-11-11 20:16:00
+ */
+@Data
+public class ParkingChangeStrategyUnitResp implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = -6153312023002477484L;
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 策略id
+     */
+    private Long strategyId;
+
+    /**
+     * 企业id
+     */
+    private Long entId;
+
+    /**
+     * 企业名称
+     */
+    private String entName;
+
+}

+ 37 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/ParkingChangeStrategyUnitSaveParam.java

@@ -0,0 +1,37 @@
+package com.sckw.transport.model.param;
+
+import com.sckw.core.web.request.PageReq;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author :donglang
+ * @version :1.0
+ * @description : 收费策略
+ * @create :2026-01-05 08:59:00
+ */
+@Data
+public class ParkingChangeStrategyUnitSaveParam extends PageReq implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = -5431003248533000828L;
+
+    /**
+     * 收费策略id
+     */
+    @NotNull(message = "收费策略id不能为空")
+    @Schema(description = "收费策略id")
+    private Long strategyId;
+
+    /**
+     * 单位id
+     */
+    @Schema(description = "单位id")
+    private List<Long> entIds;
+
+}

+ 25 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/ParkingWalletFeeEstimateQueryParam.java

@@ -0,0 +1,25 @@
+package com.sckw.transport.model.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.DecimalMin;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 服务费预估查询参数
+ */
+@Data
+public class ParkingWalletFeeEstimateQueryParam implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = -5630735374527006854L;
+
+    @NotNull(message = "采购数量不能为空")
+    @DecimalMin(value = "0", message = "采购数量不能小于0")
+    @Schema(description = "本次采购数量")
+    private BigDecimal purchaseQuantity;
+}

+ 36 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/ParkingWalletFeeEstimateResp.java

@@ -0,0 +1,36 @@
+package com.sckw.transport.model.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 服务费预估结果
+ */
+@Data
+public class ParkingWalletFeeEstimateResp implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = -5146116069901904418L;
+
+    /**
+     * 服务费余额
+     */
+    @Schema(description = "服务费余额")
+    private BigDecimal serviceFeeBalance;
+
+    /**
+     * 本次预计服务费
+     */
+    @Schema(description = "本次预计服务费")
+    private BigDecimal estimatedServiceFee;
+
+    /**
+     * 最大可购买数量(收费策略开启时,按服务费余额/策略单价计算)
+     */
+    @Schema(description = "最大可购买数量")
+    private BigDecimal maxPurchaseQuantity;
+}

+ 28 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtParkingChangeStrategyRepository.java

@@ -0,0 +1,28 @@
+package com.sckw.transport.repository;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sckw.transport.dao.KwtParkingChangeStrategyMapper;
+import com.sckw.transport.model.KwtParkingChargeStrategy;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @Author: 门卫车辆订单
+ * @CreateTime: 2025-10-12
+ * @Description:
+ * @Version: 1.0
+ */
+
+@Repository
+public class KwtParkingChangeStrategyRepository extends ServiceImpl<KwtParkingChangeStrategyMapper, KwtParkingChargeStrategy> {
+
+
+    public List<KwtParkingChargeStrategy> queryParkingChangeStrategy() {
+        return list(
+                Wrappers.<KwtParkingChargeStrategy>lambdaQuery()
+                        .orderByDesc(KwtParkingChargeStrategy::getId));
+    }
+
+}

+ 35 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtParkingChangeStrategyUnitRepository.java

@@ -0,0 +1,35 @@
+package com.sckw.transport.repository;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sckw.transport.dao.KwtParkingChangeStrategyUnitMapper;
+import com.sckw.transport.model.KwtParkingChargeStrategyUnit;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @Author: 门卫车辆订单
+ * @CreateTime: 2025-10-12
+ * @Description:
+ * @Version: 1.0
+ */
+
+@Repository
+public class KwtParkingChangeStrategyUnitRepository extends ServiceImpl<KwtParkingChangeStrategyUnitMapper, KwtParkingChargeStrategyUnit> {
+
+
+    public List<KwtParkingChargeStrategyUnit> queryByStrategyId(Long id) {
+        return list(
+                Wrappers.<KwtParkingChargeStrategyUnit>lambdaQuery()
+                        .eq(KwtParkingChargeStrategyUnit::getStrategyId, id)
+                        .orderByDesc(KwtParkingChargeStrategyUnit::getId));
+    }
+
+    public void deleteByStrategyId(Long id) {
+        remove(
+                Wrappers.<KwtParkingChargeStrategyUnit>lambdaQuery()
+                        .eq(KwtParkingChargeStrategyUnit::getStrategyId, id));
+    }
+
+}

+ 31 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtParkingWalletFeeBalanceRepository.java

@@ -0,0 +1,31 @@
+package com.sckw.transport.repository;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sckw.transport.dao.KwtParkingChangeStrategyUnitMapper;
+import com.sckw.transport.dao.KwtParkingWalletFeeBalanceMapper;
+import com.sckw.transport.model.KwtParkingChargeStrategy;
+import com.sckw.transport.model.KwtParkingChargeStrategyUnit;
+import com.sckw.transport.model.KwtParkingWalletFeeBalance;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @Author: 门卫车辆订单
+ * @CreateTime: 2025-10-12
+ * @Description:
+ * @Version: 1.0
+ */
+
+@Repository
+public class KwtParkingWalletFeeBalanceRepository extends ServiceImpl<KwtParkingWalletFeeBalanceMapper, KwtParkingWalletFeeBalance> {
+
+
+    public List<KwtParkingWalletFeeBalance> queryParkingChangeStrategy() {
+        return list(
+                Wrappers.<KwtParkingWalletFeeBalance>lambdaQuery()
+                        .orderByDesc(KwtParkingWalletFeeBalance::getId));
+    }
+
+}

+ 28 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtParkingWalletFeeRepository.java

@@ -0,0 +1,28 @@
+package com.sckw.transport.repository;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sckw.transport.dao.KwtParkingWalletFeeMapper;
+import com.sckw.transport.model.KwtParkingWalletFee;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @Author: 门卫车辆订单
+ * @CreateTime: 2025-10-12
+ * @Description:
+ * @Version: 1.0
+ */
+
+@Repository
+public class KwtParkingWalletFeeRepository extends ServiceImpl<KwtParkingWalletFeeMapper, KwtParkingWalletFee> {
+
+
+    public List<KwtParkingWalletFee> queryParkingChangeStrategy() {
+        return list(
+                Wrappers.<KwtParkingWalletFee>lambdaQuery()
+                        .orderByDesc(KwtParkingWalletFee::getId));
+    }
+
+}

+ 233 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/ParkingChangeStrategyService.java

@@ -0,0 +1,233 @@
+package com.sckw.transport.service;
+
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.sckw.core.common.enums.enums.ErrorCodeEnum;
+import com.sckw.core.exception.BusinessPlatfromException;
+import com.sckw.core.model.constant.Global;
+import com.sckw.core.model.enums.ParkingChangeStrategyEnum;
+import com.sckw.core.utils.CollectionUtils;
+import com.sckw.core.utils.StringUtils;
+import com.sckw.core.web.response.result.PageDataResult;
+import com.sckw.system.api.RemoteSystemService;
+import com.sckw.system.api.model.dto.res.EntCacheResDto;
+import com.sckw.transport.model.KwtParkingChargeStrategy;
+import com.sckw.transport.model.KwtParkingChargeStrategyUnit;
+import com.sckw.transport.model.ParkingChangeStrategySaveParam;
+import com.sckw.transport.model.param.ParkingChangeStrategyQueryParam;
+import com.sckw.transport.model.param.ParkingChangeStrategyResp;
+import com.sckw.transport.model.param.ParkingChangeStrategyUnitResp;
+import com.sckw.transport.model.param.ParkingChangeStrategyUnitSaveParam;
+import com.sckw.transport.repository.KwtParkingChangeStrategyRepository;
+import com.sckw.transport.repository.KwtParkingChangeStrategyUnitRepository;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * Author: donglang
+ * Time: 2026-01-05
+ * Des: 收费策略 Service
+ * Version: 1.0
+ */
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class ParkingChangeStrategyService {
+
+
+    private final KwtParkingChangeStrategyRepository parkingChangeStrategyRepository;
+    private final KwtParkingChangeStrategyUnitRepository parkingChangeStrategyUnitRepository;
+
+    @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
+   RemoteSystemService remoteSystemService;
+
+    /**
+     * 分页查询收费策略
+     * @param param
+     */
+    public PageDataResult<ParkingChangeStrategyResp> pageQueryChangeStrategy(ParkingChangeStrategyQueryParam param) {
+        log.info("分页查询收费策略:{}", JSON.toJSONString(param));
+        if (param.getEntId() == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "平台企业id不能为空!");
+        }
+
+        //构建查询条件
+        LambdaQueryWrapper<KwtParkingChargeStrategy> wrapper = buildAndExecuteQuery(param);
+
+        //查询门卫订单
+        Page<KwtParkingChargeStrategy> pageByStatus = parkingChangeStrategyRepository.page(new Page<>(param.getPageNum(), param.getPageSize()), wrapper);
+        List<KwtParkingChargeStrategy> records = pageByStatus.getRecords();
+        if (CollectionUtils.isEmpty(records)) {
+            log.info("当前收费策略信息");
+            return PageDataResult.empty(param.getPageNum(), param.getPageSize());
+        }
+        List<ParkingChangeStrategyResp> changeStrategyRespList = getChangeStrategyPageResult(records);
+        return PageDataResult.success(param.getPageNum(), param.getPageSize(), pageByStatus.getTotal(), changeStrategyRespList);
+    }
+
+
+    /**
+     * 构建查询条件并执行分页查询
+     */
+    private LambdaQueryWrapper<KwtParkingChargeStrategy> buildAndExecuteQuery(ParkingChangeStrategyQueryParam param) {
+        return  Wrappers.<KwtParkingChargeStrategy>lambdaQuery()
+                .eq(param.getType() != null, KwtParkingChargeStrategy::getType, param.getType())
+                .like(StringUtils.isNotBlank(param.getStrategyName()), KwtParkingChargeStrategy::getStrategyName, param.getStrategyName())
+                .orderByDesc(KwtParkingChargeStrategy::getCreateBy);
+    }
+
+    /**
+     * 获取收费策略
+     * @param records
+     */
+    private List<ParkingChangeStrategyResp> getChangeStrategyPageResult(List<KwtParkingChargeStrategy> records) {
+        log.info("开始查询收费策略,param:{}", JSON.toJSONString(records));
+        if (CollectionUtils.isEmpty(records)) {
+            return Collections.emptyList();
+        }
+        List<ParkingChangeStrategyResp> changeStrategyList = records.stream()
+                .map(change -> {
+                    ParkingChangeStrategyResp resp = new ParkingChangeStrategyResp();
+                    resp.setId(change.getId());
+                    resp.setStrategyName(change.getStrategyName());
+                    resp.setType(change.getType());
+                    resp.setTypeDesc(ParkingChangeStrategyEnum.geDesc(change.getType()));
+                    resp.setMethod(change.getMethod());
+
+                    if (Objects.equals(ParkingChangeStrategyEnum.BY_TON, change.getType())) {
+                        resp.setMethodDesc(change.getMethod() + "元/吨");
+                    } else if (Objects.equals(ParkingChangeStrategyEnum.BY_TIME, change.getType())) {
+                        resp.setMethodDesc(change.getMethod() + "元/次");
+                    } else {
+                        resp.setMethodDesc(change.getMethod() + "元/月");
+                    }
+                    // 查询分配单位数量
+                    List<KwtParkingChargeStrategyUnit> strategyUnitList = parkingChangeStrategyUnitRepository.queryByStrategyId(change.getId());
+                    if (CollectionUtils.isEmpty(strategyUnitList)) {
+                        resp.setEntNumber(0);
+                    } else {
+                        resp.setEntNumber(strategyUnitList.size());
+                    }
+                    resp.setStatus(change.getStatus());
+                    resp.setRemark(change.getRemark());
+                    resp.setCreateTime(change.getCreateTime());
+                    return resp;
+                }).collect(Collectors.toList());
+
+        log.info("收费策略查询结束,size:{}", JSON.toJSONString(changeStrategyList.size()));
+        return changeStrategyList;
+
+    }
+
+
+    /**
+     * 保存收费策略
+     * @param param
+     */
+    public void saveChangeStrategy(ParkingChangeStrategySaveParam param) {
+        log.info("保存收费策略,param:{}", JSON.toJSONString(param));
+        // 新增
+        if (param.getId() == null) {
+            KwtParkingChargeStrategy changeStrategy = new KwtParkingChargeStrategy();
+            changeStrategy.setStrategyName(param.getStrategyName());
+            changeStrategy.setType(param.getType());
+            changeStrategy.setMethod(param.getMethod());
+            changeStrategy.setStatus(1);
+            changeStrategy.setRemark(param.getRemark());
+            parkingChangeStrategyRepository.save(changeStrategy);
+        } else {
+            // 更新
+            KwtParkingChargeStrategy changeStrategy = parkingChangeStrategyRepository.getById(param.getId());
+            if (changeStrategy == null) {
+                throw new BusinessPlatfromException(ErrorCodeEnum.DRIVER_NOT_FOUND, "收费策略不存在");
+            }
+            changeStrategy.setStrategyName(param.getStrategyName());
+            changeStrategy.setType(param.getType());
+            changeStrategy.setMethod(param.getMethod());
+            changeStrategy.setStatus(param.getStatus());
+            changeStrategy.setRemark(param.getRemark());
+            parkingChangeStrategyRepository.updateById(changeStrategy);
+        }
+    }
+
+    /**
+     * 删除收费策略
+     * @param id
+     */
+    public void deleteChangeStrategy(Long id) {
+        log.info("删除收费策略,id:{}", id);
+        // 新增
+        if (id == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.DRIVER_NOT_FOUND, "id不存在");
+        }
+        KwtParkingChargeStrategy changeStrategy = parkingChangeStrategyRepository.getById(id);
+        if (changeStrategy == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.DRIVER_NOT_FOUND, "收费策略不存在");
+        }
+        changeStrategy.setDelFlag(Global.YES);
+        parkingChangeStrategyRepository.updateById(changeStrategy);
+    }
+
+    /**
+     * 查询收费策略已分配单位
+     * @param id
+     * @return List<ParkingChangeStrategyUnitResp>
+     */
+    public List<ParkingChangeStrategyUnitResp> queryChangeStrategyEnt(Long id) {
+        log.info("查询收费策略已分配单位,id:{}", id);
+        List<KwtParkingChargeStrategyUnit> strategyUnitList = parkingChangeStrategyUnitRepository.queryByStrategyId(id);
+        if (CollectionUtils.isEmpty(strategyUnitList)) {
+            return Collections.emptyList();
+        }
+        return strategyUnitList.stream()
+                .map(unit -> {
+                    ParkingChangeStrategyUnitResp resp = new ParkingChangeStrategyUnitResp();
+                    resp.setId(unit.getId());
+                    resp.setStrategyId(id);
+                    resp.setEntId(unit.getEntId());
+
+                    // 查询企业名称
+                    EntCacheResDto entCacheResDto = remoteSystemService.queryEntDetails(unit.getEntId());
+                    resp.setEntName(entCacheResDto.getFirmName());
+                    return resp;
+                }).collect(Collectors.toList());
+    }
+
+    /**
+     * 保存单位分配
+     * @param param
+     */
+    public void saveChangeStrategyEnt(ParkingChangeStrategyUnitSaveParam param) {
+        log.info("保存单位分配,param:{}", JSON.toJSONString(param));
+        // 如果企业id为空,删除所以的单位关联关系
+        if (CollectionUtils.isEmpty(param.getEntIds())) {
+            parkingChangeStrategyUnitRepository.deleteByStrategyId(param.getStrategyId());
+        } else {
+            parkingChangeStrategyUnitRepository.deleteByStrategyId(param.getStrategyId());
+            // 构建关联表实体列表
+            List<KwtParkingChargeStrategyUnit> insertList = param.getEntIds().stream()
+                    .map(entId -> {
+                        KwtParkingChargeStrategyUnit unit = new KwtParkingChargeStrategyUnit();
+                        unit.setStrategyId(param.getStrategyId());
+                        unit.setEntId(entId);
+                        return unit;
+                    })
+                    .collect(Collectors.toList());
+
+            // 批量插入
+            parkingChangeStrategyUnitRepository.saveBatch(insertList);
+        }
+    }
+
+}

+ 202 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/ParkingWalletFeeService.java

@@ -0,0 +1,202 @@
+package com.sckw.transport.service;
+
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.sckw.core.common.enums.enums.ErrorCodeEnum;
+import com.sckw.core.exception.BusinessPlatfromException;
+import com.sckw.core.model.constant.Global;
+import com.sckw.core.web.context.LoginUserHolder;
+import com.sckw.transport.model.KwtParkingChargeStrategy;
+import com.sckw.transport.model.KwtParkingChargeStrategyUnit;
+import com.sckw.transport.model.KwtParkingWalletFee;
+import com.sckw.transport.model.param.ParkingWalletFeeEstimateQueryParam;
+import com.sckw.transport.model.param.ParkingWalletFeeEstimateResp;
+import com.sckw.transport.repository.KwtParkingChangeStrategyRepository;
+import com.sckw.transport.repository.KwtParkingChangeStrategyUnitRepository;
+import com.sckw.system.api.RemoteSystemService;
+import com.sckw.transport.repository.KwtParkingWalletFeeBalanceRepository;
+import com.sckw.transport.repository.KwtParkingWalletFeeRepository;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Author: donglang
+ * Time: 2026-01-05
+ * Des: 收费策略 Service
+ * Version: 1.0
+ */
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class ParkingWalletFeeService {
+
+
+    private static final BigDecimal ZERO_AMOUNT = BigDecimal.ZERO;
+    private static final int STRATEGY_OPEN = 1;
+
+    private final KwtParkingWalletFeeRepository parkingWalletFeeRepository;
+    private final KwtParkingWalletFeeBalanceRepository parkingWalletFeeBalanceRepository;
+    private final KwtParkingChangeStrategyRepository parkingChangeStrategyRepository;
+    private final KwtParkingChangeStrategyUnitRepository parkingChangeStrategyUnitRepository;
+
+    @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
+    RemoteSystemService remoteSystemService;
+
+    /**
+     * 查询服务费余额、本次预计服务费与最大可购买数量
+     * 规则:
+     * 1. 服务费余额 = 采购方当前服务费余额
+     * 2. 本次预计服务费 = 采购数量 * 采购方当前配置的收费策略单价
+     * 3. 最大可购买数量 = 收费策略开启时,服务费余额 / 策略单价;未开启时不返回余额约束
+     *
+     * @param param 查询参数
+     * @return 服务费余额、本次预计服务费与最大可购买数量
+     */
+    public ParkingWalletFeeEstimateResp queryEstimateServiceFee(ParkingWalletFeeEstimateQueryParam param) {
+        Long entId = LoginUserHolder.getEntId();
+        log.info("服务费预估开始,entId:{}, param:{}", entId, param);
+        if (param.getPurchaseQuantity() == null || param.getPurchaseQuantity().compareTo(ZERO_AMOUNT) < 0) {
+            log.warn("服务费预估参数异常,采购数量非法,entId:{}, purchaseQuantity:{}",
+                    entId, param.getPurchaseQuantity());
+            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "采购数量不能为空且不能小于0");
+        }
+
+        // 查询采购方当前服务费余额
+        BigDecimal serviceFeeBalance = queryServiceFeeBalance(entId);
+
+        // 查询当前企业生效中的收费策略(仅取状态开启的最新一条)
+        KwtParkingChargeStrategy currentStrategy = queryCurrentEnableStrategy(entId);
+        BigDecimal currentStrategyUnitFee = currentStrategy == null || currentStrategy.getMethod() == null
+                ? ZERO_AMOUNT : currentStrategy.getMethod();
+        log.info("服务费预估策略信息,entId:{}, strategyId:{}, strategyStatus:{}, unitFee:{}",
+                entId,
+                currentStrategy == null ? null : currentStrategy.getId(),
+                currentStrategy == null ? null : currentStrategy.getStatus(),
+                currentStrategyUnitFee);
+
+        // 本次预计服务费 = 采购数量 * 策略单价,金额统一保留2位
+        BigDecimal estimatedServiceFee = param.getPurchaseQuantity().multiply(currentStrategyUnitFee)
+                .setScale(2, RoundingMode.HALF_UP);
+
+        // 收费策略开关开启时,按服务费余额计算最大可购买数量
+        BigDecimal maxPurchaseQuantity = calculateMaxPurchaseQuantity(currentStrategy, currentStrategyUnitFee, serviceFeeBalance);
+        log.info("服务费预估计算完成,entId:{}, purchaseQuantity:{}, serviceFeeBalance:{}, estimatedServiceFee:{}, maxPurchaseQuantity:{}",
+                entId, param.getPurchaseQuantity(), serviceFeeBalance, estimatedServiceFee, maxPurchaseQuantity);
+
+        ParkingWalletFeeEstimateResp resp = new ParkingWalletFeeEstimateResp();
+        resp.setServiceFeeBalance(serviceFeeBalance);
+        resp.setEstimatedServiceFee(estimatedServiceFee);
+        resp.setMaxPurchaseQuantity(maxPurchaseQuantity);
+        log.info("服务费预估结束,entId:{}, resp:{}", entId, resp);
+        return resp;
+    }
+
+    /**
+     * 计算服务费余额支持的最大可购买数量
+     * 仅在收费策略开关开启且单价大于0时计算:服务费余额 / 策略单价(向下取整,保留4位小数)
+     *
+     * @param currentStrategy       当前收费策略
+     * @param currentStrategyUnitFee 策略单价
+     * @param serviceFeeBalance     服务费余额
+     * @return 最大可购买数量;策略未开启时不做余额约束,返回null
+     */
+    private BigDecimal calculateMaxPurchaseQuantity(KwtParkingChargeStrategy currentStrategy,
+                                                    BigDecimal currentStrategyUnitFee,
+                                                    BigDecimal serviceFeeBalance) {
+        if (currentStrategy == null || !Objects.equals(currentStrategy.getStatus(), STRATEGY_OPEN)
+                || currentStrategyUnitFee.compareTo(ZERO_AMOUNT) <= 0) {
+            log.info("最大可购买数量未计算,原因:{}",
+                    currentStrategy == null ? "未匹配到收费策略" : "收费策略未开启或单价<=0");
+            return null;
+        }
+        BigDecimal maxPurchaseQuantity = serviceFeeBalance.divide(currentStrategyUnitFee, 4, RoundingMode.DOWN);
+        log.info("最大可购买数量计算完成,serviceFeeBalance:{}, unitFee:{}, maxPurchaseQuantity:{}",
+                serviceFeeBalance, currentStrategyUnitFee, maxPurchaseQuantity);
+        return maxPurchaseQuantity.max(ZERO_AMOUNT);
+    }
+
+    /**
+     * 查询企业当前生效的收费策略
+     * 逻辑:先查企业绑定的策略,再查策略详情,最后取“开启状态”且id最大(最新)的一条
+     *
+     * @param proEntId 采购企业id
+     * @return 生效策略;未匹配到则返回null
+     */
+    private KwtParkingChargeStrategy queryCurrentEnableStrategy(Long proEntId) {
+        List<KwtParkingChargeStrategyUnit> strategyUnitList = parkingChangeStrategyUnitRepository.list(
+                Wrappers.<KwtParkingChargeStrategyUnit>lambdaQuery()
+                        .eq(KwtParkingChargeStrategyUnit::getEntId, proEntId)
+                        .eq(KwtParkingChargeStrategyUnit::getDelFlag, Global.NO)
+        );
+        log.info("查询企业策略绑定关系,proEntId:{}, bindCount:{}",
+                proEntId, strategyUnitList == null ? 0 : strategyUnitList.size());
+
+        if (CollectionUtils.isEmpty(strategyUnitList)) {
+            log.info("企业未绑定任何策略,proEntId:{}, strategyUnitList:[]", proEntId);
+            return null;
+        }
+        List<Long> strategyIds = strategyUnitList.stream()
+                .map(KwtParkingChargeStrategyUnit::getStrategyId)
+                .filter(Objects::nonNull)
+                .toList();
+        log.info("查询企业策略ID集合,proEntId:{}, strategyIds:{}", proEntId, strategyIds);
+        if (CollectionUtils.isEmpty(strategyIds)) {
+            log.info("企业绑定策略ID集合为空");
+            return null;
+        }
+        List<KwtParkingChargeStrategy> strategyList = parkingChangeStrategyRepository.list(
+                Wrappers.<KwtParkingChargeStrategy>lambdaQuery()
+                        .in(KwtParkingChargeStrategy::getId, strategyIds)
+                        .eq(KwtParkingChargeStrategy::getDelFlag, Global.NO)
+                        .orderByDesc(KwtParkingChargeStrategy::getId)
+        );
+        log.info("查询策略详情完成,proEntId:{}, strategyCount:{}",
+                proEntId, strategyList == null ? 0 : strategyList.size());
+        if (CollectionUtils.isEmpty(strategyList)) {
+            return null;
+        }
+        KwtParkingChargeStrategy hitStrategy = strategyList.stream()
+                .filter(item -> Objects.equals(item.getStatus(), STRATEGY_OPEN))
+                .max(Comparator.comparing(KwtParkingChargeStrategy::getId))
+                .orElse(null);
+        log.info("匹配生效策略结果,proEntId:{}, hitStrategyId:{}",
+                proEntId, hitStrategy == null ? null : hitStrategy.getId());
+        return hitStrategy;
+    }
+
+    /**
+     * 查询企业当前可用服务费余额
+     *
+     * @param proEntId 采购企业id
+     * @return 服务费余额,无记录时返回0
+     */
+    private BigDecimal queryServiceFeeBalance(Long proEntId) {
+        KwtParkingWalletFee walletFee = parkingWalletFeeRepository.getOne(
+                Wrappers.<KwtParkingWalletFee>lambdaQuery()
+                        .eq(KwtParkingWalletFee::getProEntId, proEntId)
+                        .eq(KwtParkingWalletFee::getDelFlag, Global.NO)
+                        .orderByDesc(KwtParkingWalletFee::getId)
+                        .last("limit 1"),
+                false
+        );
+        if (walletFee == null || walletFee.getServiceFeeBalance() == null) {
+            log.info("查询服务费余额为空,按0处理,proEntId:{}", proEntId);
+            return ZERO_AMOUNT;
+        }
+        log.info("查询服务费余额成功,proEntId:{}, serviceFeeBalance:{}",
+                proEntId, walletFee.getServiceFeeBalance());
+        return walletFee.getServiceFeeBalance();
+    }
+
+
+}

+ 64 - 0
sql/2026/06/2026_06_16_create.sql

@@ -0,0 +1,64 @@
+
+create table kwt_parking_charge_strategy
+(
+    id                              bigint          NOT NULL AUTO_INCREMENT COMMENT '主键',
+    strategy_name                   varchar(20)     NOT NULL default '' COMMENT '策略名称',
+    type                            int             NOT NULL DEFAULT '0' COMMENT '策略类型(1-按吨计费,2-按次计费、3-按月计费)',
+    method                          decimal(10,2)   NOT NULL DEFAULT 0.00 COMMENT '计价方式',
+    status                          int             NOT NULL DEFAULT '0' COMMENT '状态(0-关闭,1-开启)',
+    remark                          varchar(20)     DEFAULT NULL COMMENT '备注',
+    del_flag                        int             NOT NULL DEFAULT '0' COMMENT '是否删除(0未删除,1删除)',
+    create_time                     datetime        NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    update_time                     datetime        NOT NULL DEFAULT CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT '更新时间',
+    create_user                     bigint          NOT NULL DEFAULT '-1' COMMENT '创建人',
+    update_user                     bigint          NOT NULL DEFAULT '-1' COMMENT '更新人',
+    PRIMARY KEY (`id`) USING BTREE
+) comment '收费策略表';
+
+
+create table kwt_parking_charge_strategy_unit
+(
+    id                              bigint          NOT NULL AUTO_INCREMENT COMMENT '主键',
+    strategy_id                     bigint          NOT NULL DEFAULT '-1' COMMENT '策略id',
+    ent_id                          bigint          NOT NULL DEFAULT '-1' COMMENT '企业id',
+    del_flag                        int             NOT NULL DEFAULT '0' COMMENT '是否删除(0未删除,1删除)',
+    create_time                     datetime        NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    update_time                     datetime        NOT NULL DEFAULT CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT '更新时间',
+    create_user                     bigint          NOT NULL DEFAULT '-1' COMMENT '创建人',
+    update_user                     bigint          NOT NULL DEFAULT '-1' COMMENT '更新人',
+    PRIMARY KEY (`id`) USING BTREE
+) comment '收费策略企业关联表';
+
+
+CREATE TABLE `kwt_parking_wallet_fee` (
+                                          `id`                            bigint          NOT NULL AUTO_INCREMENT COMMENT '主键',
+                                          `pro_ent_id`                    bigint          NOT NULL DEFAULT '-1' COMMENT '采购商企业id',
+                                          `service_fee_balance`           decimal(16,2)   NOT NULL DEFAULT '0.00' COMMENT '服务费余额',
+                                          `trading_amount`                decimal(16,2)   NOT NULL DEFAULT '0.00' COMMENT '履约中金额',
+                                          `voucher_url`                   longtext        CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '凭证图片',
+                                          `remark`                        varchar(20)     DEFAULT NULL DEFAULT '' COMMENT '备注',
+                                          del_flag                        int             NOT NULL DEFAULT '0' COMMENT '是否删除(0未删除,1删除)',
+                                          create_time                     datetime        NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+                                          update_time                     datetime        NOT NULL DEFAULT CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT '更新时间',
+                                          create_user                     bigint          NOT NULL DEFAULT '-1' COMMENT '创建人',
+                                          update_user                     bigint          NOT NULL DEFAULT '-1' COMMENT '更新人',
+                                          PRIMARY KEY (`id`) USING BTREE
+) comment '预存服务费';
+
+
+CREATE TABLE `kwt_parking_wallet_fee_balance` (
+                                                  `id`                            bigint          NOT NULL AUTO_INCREMENT COMMENT '主键',
+                                                  `order_no`                      varchar(32)     CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '关联订单编号',
+                                                  `pro_ent_id`                    bigint          NOT NULL DEFAULT '-1' COMMENT '采购商企业id',
+                                                  `trade_type`                    int             NOT NULL DEFAULT '0' COMMENT '交易类型 2-预付 3-收益 4-冻结 5-解冻 6-消费 9-人工录入',
+                                                  `trade_amount`                  decimal(16,2)   NOT NULL DEFAULT '0.00' COMMENT '交易金额',
+                                                  `service_fee_balance`           decimal(16,2)   NOT NULL DEFAULT '0.00' COMMENT '服务费余额',
+                                                  `trading_amount`                decimal(16,2)   NOT NULL DEFAULT '0.00' COMMENT '履约中金额',
+                                                  `remark`                        varchar(20)     DEFAULT NULL DEFAULT '' COMMENT '备注',
+                                                  del_flag                        int             NOT NULL DEFAULT '0' COMMENT '是否删除(0未删除,1删除)',
+                                                  create_time                     datetime        NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+                                                  update_time                     datetime        NOT NULL DEFAULT CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT '更新时间',
+                                                  create_user                     bigint          NOT NULL DEFAULT '-1' COMMENT '创建人',
+                                                  update_user                     bigint          NOT NULL DEFAULT '-1' COMMENT '更新人',
+                                                  PRIMARY KEY (`id`) USING BTREE
+) comment '预存服务费明细';