Prechádzať zdrojové kódy

预付、运费冻结解冻消费功能

tangyishan 2 mesiacov pred
rodič
commit
0bde2f56bc
39 zmenil súbory, kde vykonal 835 pridanie a 217 odobranie
  1. 1 1
      sckw-auth/src/main/resources/bootstrap-test.yml
  2. 1 1
      sckw-gateway/src/main/resources/bootstrap-test.yml
  3. 6 0
      sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/model/dto/res/ContractCommonInfoResDto.java
  4. 1 1
      sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/model/dto/res/ContractDetailRespVo.java
  5. 1 1
      sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/model/dto/res/ContractTradeOrderInfo.java
  6. 1 1
      sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/model/vo/TradeContractResDto.java
  7. 0 39
      sckw-modules-api/sckw-payment-api/src/main/java/com/sckw/payment/api/feign/OfflineWalletFeignService.java
  8. 46 0
      sckw-modules-api/sckw-payment-api/src/main/java/com/sckw/payment/api/feign/PaymentFeignService.java
  9. 0 32
      sckw-modules-api/sckw-payment-api/src/main/java/com/sckw/payment/api/model/dto/WalletFreezeDto.java
  10. 47 0
      sckw-modules-api/sckw-payment-api/src/main/java/com/sckw/payment/api/model/feign/WalletPayableDto.java
  11. 44 0
      sckw-modules-api/sckw-payment-api/src/main/java/com/sckw/payment/api/model/feign/WalletPrepaidDto.java
  12. 5 0
      sckw-modules/sckw-contract/pom.xml
  13. 1 1
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/controller/KwcLogisticsContractController.java
  14. 1 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/dubbo/RemoteContractServiceImpl.java
  15. 5 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/entity/KwcContractLogistics.java
  16. 1 1
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/entity/KwcContractTrade.java
  17. 8 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/LogisticListReq.java
  18. 2 2
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/SupplyContractTradeReq.java
  19. 1 1
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/TradeBaseInfoReqVo.java
  20. 1 1
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/res/ContractDetailResp.java
  21. 32 1
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/service/operateService/KwcContractLogisticsService.java
  22. 31 1
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/service/operateService/KwcContractTradeService.java
  23. 1 1
      sckw-modules/sckw-contract/src/main/resources/bootstrap-test.yml
  24. 1 1
      sckw-modules/sckw-file/src/main/resources/bootstrap-test.yml
  25. 33 0
      sckw-modules/sckw-order/src/main/java/com/sckw/order/config/FeignConfig.java
  26. 11 0
      sckw-modules/sckw-order/src/main/java/com/sckw/order/model/KwoTradeOrder.java
  27. 133 100
      sckw-modules/sckw-order/src/main/java/com/sckw/order/serivce/KwoTradeOrderService.java
  28. 110 25
      sckw-modules/sckw-order/src/main/java/com/sckw/order/task/TradeOrderTask.java
  29. 1 1
      sckw-modules/sckw-order/src/main/resources/mapper/KwoTradeOrderMapper.xml
  30. 1 1
      sckw-modules/sckw-system/src/main/resources/bootstrap-test.yml
  31. 6 0
      sckw-modules/sckw-transport/pom.xml
  32. 54 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/UnloadingHandler.java
  33. 5 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/KwtLogisticsOrder.java
  34. 5 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/dto/LogisticData.java
  35. 43 3
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtAcceptCarriageOrderService.java
  36. 63 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtLogisticsConsignmentService.java
  37. 53 1
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtWaybillOrderV1Service.java
  38. 69 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/task/LogisticsOrderCompletionTask.java
  39. 10 0
      sql/2026/04/2026_04_02_tangyishan_alter.sql

+ 1 - 1
sckw-auth/src/main/resources/bootstrap-test.yml

@@ -5,7 +5,7 @@ spring:
         # 服务注册地址
         server-addr: @nacos.server@
         # 命名空间
-        namespace: @nacos.namespace@
+        namespace: sckw-ng-service-platform-dev-tys
         # 共享配置
         group: sckw-ng-service-platform
       config:

+ 1 - 1
sckw-gateway/src/main/resources/bootstrap-test.yml

@@ -5,7 +5,7 @@ spring:
         # 服务注册地址
         server-addr: @nacos.server@
         # 命名空间
-        namespace: @nacos.namespace@
+        namespace: sckw-ng-service-platform-dev-tys
         # 共享配置
         group: sckw-ng-service-platform
       config:

+ 6 - 0
sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/model/dto/res/ContractCommonInfoResDto.java

@@ -73,4 +73,10 @@ public class ContractCommonInfoResDto implements Serializable {
     private Long salesmanId;
 
 
+    /**
+     * 结算方式(1普通结算、2记账模式)
+     */
+    private Integer settlement;
+
+
 }

+ 1 - 1
sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/model/dto/res/ContractDetailRespVo.java

@@ -151,7 +151,7 @@ public class ContractDetailRespVo implements Serializable {
         private Date startTime;
 
         /**
-         * 结算方式
+         * 结算方式 1-普通结算 2-预付制结算
          */
         @Schema(description = "结算方式")
         private Integer settlement;

+ 1 - 1
sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/model/dto/res/ContractTradeOrderInfo.java

@@ -128,7 +128,7 @@ public class ContractTradeOrderInfo implements Serializable {
     private String businessId;
 
     /**
-     * 结算方式
+     * 结算方式 1-普通结算 2-预付制结算
      */
 
     private Integer settlement;

+ 1 - 1
sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/model/vo/TradeContractResDto.java

@@ -64,7 +64,7 @@ public class TradeContractResDto implements Serializable {
     private Long contractPid;
     private Integer status;
     /**
-     * 结算方式
+     * 结算方式 1-普通结算 2-预付制结算
      */
     private Integer settlement;
 

+ 0 - 39
sckw-modules-api/sckw-payment-api/src/main/java/com/sckw/payment/api/feign/OfflineWalletFeignService.java

@@ -1,39 +0,0 @@
-package com.sckw.payment.api.feign;
-
-import com.sckw.core.web.response.BaseResult;
-import com.sckw.payment.api.model.dto.WalletFreezeDto;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.cloud.openfeign.FeignClient;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-
-import java.math.BigDecimal;
-
-/**
- * 线下钱包Feign接口
- * @author cxf
- */
-@FeignClient(name = "sckw-payment-new", url = "${wallet.api.base-url}/walletPrepaid", contextId = "OfflineWalletFeignService")
-@ConditionalOnProperty(name = "wallet.api.base-url")
-public interface OfflineWalletFeignService {
-
-    /**
-     * 验证线下钱包预付余额是否足够
-     */
-    @GetMapping("/queryPrepaidBalance")
-    BaseResult<BigDecimal> queryPrepaidBalance(Long entityId);
-
-    /**
-     * 线下钱包扣减预付余额、增加冻结金额
-     */
-    @PostMapping("/freezeBalance")
-    BaseResult<Boolean> freezeBalance(@RequestBody WalletFreezeDto req);
-
-    /**
-     * 线下钱包加回预付余额、减冻结金额
-     */
-    @PostMapping("/unfreezeBalance")
-    BaseResult<Boolean> unfreezeBalance(@RequestBody WalletFreezeDto req);
-
-}

+ 46 - 0
sckw-modules-api/sckw-payment-api/src/main/java/com/sckw/payment/api/feign/PaymentFeignService.java

@@ -0,0 +1,46 @@
+package com.sckw.payment.api.feign;
+
+import com.sckw.core.web.response.BaseResult;
+import com.sckw.payment.api.model.feign.WalletPrepaidDto;
+import com.sckw.payment.api.model.feign.WalletPayableDto;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.math.BigDecimal;
+
+@FeignClient(name = "sckw-payment-new",contextId = "paymentFeignService")
+public interface PaymentFeignService {
+
+    @GetMapping("/walletPrepaid/queryPrepaidBalance")
+    BaseResult<BigDecimal> queryPrepaidBalance(@RequestParam("supEntId") Long supEntId);
+
+    /**
+     * 初始化预付清单
+     */
+    @PostMapping("/initPayable")
+    BaseResult<Object> initPrepaidBalance(@RequestBody WalletPrepaidDto prepaidDto);
+
+    /**
+     * 预付清单冻结、解冻、消费接口
+     */
+    @PostMapping("/updatePrepaidBalance")
+    BaseResult<Object> updatePrepaidBalance(@RequestBody WalletPrepaidDto prepaidDto);
+
+    /**
+     * 初始化运费清单
+     */
+    @PostMapping("/initPayable")
+    BaseResult<Object> initPayable(@RequestBody WalletPayableDto payableAddDto);
+
+    /**
+     * 运费清单冻结、解冻、消费接口
+     */
+    @PostMapping("/updatePayable")
+    BaseResult<Object> updatePayable(@RequestBody @Validated WalletPayableDto payableUpdateDto);
+
+
+}

+ 0 - 32
sckw-modules-api/sckw-payment-api/src/main/java/com/sckw/payment/api/model/dto/WalletFreezeDto.java

@@ -1,32 +0,0 @@
-package com.sckw.payment.api.model.dto;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.math.BigDecimal;
-
-/**
- * 余额冻结参数
- *
- * @author cxf
- * @since 2026-03-06  08:46
- */
-@Data
-public class WalletFreezeDto implements Serializable {
-    @Serial
-    private static final long serialVersionUID = 6079448481420817882L;
-    //采购商企业id
-    @Schema(description = "采购商企业id")
-    private Long proEntId;
-    //供应商id
-    @Schema(description = "供应商id")
-    private Long supEntId;
-    //冻结金额
-    @Schema(description = "冻结金额")
-    private BigDecimal freezeAmount;
-    //订单号
-    @Schema(description = "订单号")
-    private String orderNo;
-}

+ 47 - 0
sckw-modules-api/sckw-payment-api/src/main/java/com/sckw/payment/api/model/feign/WalletPayableDto.java

@@ -0,0 +1,47 @@
+package com.sckw.payment.api.model.feign;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 运费清单新增或修改参数
+ *
+ * @author tangyishan
+ * @since 2026-03-18  14:43
+ */
+@Data
+public class WalletPayableDto {
+    /** 托运企业id */
+    @Schema(description = "托运企业id")
+    @NotNull(message = "托运企业id不能为空")
+    private Long consignEntId;
+
+    /** 承运企业id */
+    @Schema(description = "承运企业id")
+    @NotNull(message = "承运企业id不能为空")
+    private Long carriageEntId;
+
+    /** 关联订单编号 */
+    @Schema(description = "关联订单编号")
+    private String orderNo;
+    /** 订单类型 5-物流订单号 6-支付订单号 */
+    @Schema(description = "订单类型 5-物流订单号 6-支付订单号")
+    private Integer orderType;
+
+
+    /** 交易类型 3-收益 4-冻结 5-解冻 6-消费 9-人工录入 10-申请付款 11-付款成功 */
+    @NotNull(message = "交易类型不能为空")
+    @Schema(description = "交易类型 3-收益 4-冻结 5-解冻 6-消费 9-人工录入 10-申请付款 11-付款成功")
+    private Integer tradeType;
+
+    /** 交易金额 */
+    @Schema(description = "交易金额")
+    @NotNull(message = "交易金额不能为空")
+    private BigDecimal tradeAmount;
+    /** 备注 */
+    @Schema(description = "备注")
+    private String remark;
+}

+ 44 - 0
sckw-modules-api/sckw-payment-api/src/main/java/com/sckw/payment/api/model/feign/WalletPrepaidDto.java

@@ -0,0 +1,44 @@
+package com.sckw.payment.api.model.feign;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 余额冻结参数
+ *
+ * @author tangyishan
+ * @since 2026-03-06  08:46
+ */
+@Data
+public class WalletPrepaidDto {
+    //采购商企业id
+    @Schema(description = "采购商企业id")
+    private Long proEntId;
+    //供应商id
+    @Schema(description = "供应商企业id")
+    private Long supEntId;
+    //关联订单编号
+    @Schema(description = "关联订单编号")
+    private String orderNo;
+
+    /** 订单类型 2-预付订单  4-贸易订单 */
+    @Schema(description = "订单类型 2-预付订单  4-贸易订单")
+    private Integer orderType;
+
+
+    /** 交易类型 2-预付 3-收益 4-冻结 5-解冻 6-消费 9-人工录入 */
+    @NotNull(message = "交易类型不能为空")
+    @Schema(description = "交易类型 2-预付 3-收益 4-冻结 5-解冻 6-消费 9-人工录入")
+    private Integer tradeType;
+
+    //交易金额
+    @Schema(description = "交易金额")
+    private BigDecimal tradeAmount;
+
+    //备注
+    @Schema(description = "备注")
+    private String remark;
+}

+ 5 - 0
sckw-modules/sckw-contract/pom.xml

@@ -104,6 +104,11 @@
             <artifactId>sckw-fleet-api</artifactId>
             <version>${basic.version}</version>
         </dependency>
+        <dependency>
+            <groupId>com.sckw</groupId>
+            <artifactId>sckw-payment-api</artifactId>
+            <version>${basic.version}</version>
+        </dependency>
         <dependency>
             <groupId>com.sckw</groupId>
             <artifactId>sckw-common-stream</artifactId>

+ 1 - 1
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/controller/KwcLogisticsContractController.java

@@ -69,7 +69,7 @@ public class KwcLogisticsContractController {
     }
 
     /**
-     * 修改合同状态
+     * 修改合同状态、签约
      */
     @PostMapping("/updateLogistics")
     @Operation(summary = "手动完结")

+ 1 - 0
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/dubbo/RemoteContractServiceImpl.java

@@ -369,6 +369,7 @@ public class RemoteContractServiceImpl implements RemoteContractService {
         contractCommonInfoResDto.setStatus(kwcContractLogistics.getStatus());
         contractCommonInfoResDto.setStatusName(Objects.requireNonNull(ContractStatusEnum.getName(kwcContractLogistics.getStatus())).getName());
         contractCommonInfoResDto.setDispatchWay(kwcContractLogistics.getDispatchWay());
+        contractCommonInfoResDto.setSettlement(kwcContractLogistics.getSettlement());
         List<KwcContractLogisticsUnit> kwcContractLogisticsUnits = kwcContractLogisticsUnitService.queryByContractId(kwcContractLogistics.getId());
         if (CollectionUtils.isNotEmpty(kwcContractLogisticsUnits)) {
             for (KwcContractLogisticsUnit kwcContractLogisticsUnit : kwcContractLogisticsUnits) {

+ 5 - 0
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/entity/KwcContractLogistics.java

@@ -56,6 +56,11 @@ public class KwcContractLogistics implements Serializable {
      * 派车方式(1手动派车、2自动派车)
      */
     private Integer dispatchWay;
+
+    /**
+     * 结算方式(1普通结算、2记账模式)
+     */
+    private Integer settlement;
     /**
      * 开始日期
      */

+ 1 - 1
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/entity/KwcContractTrade.java

@@ -131,7 +131,7 @@ public class KwcContractTrade implements Serializable {
     private String businessId;
 
     /**
-     * 结算方式
+     * 结算方式 1-普通结算 2-预付制结算
      */
     @TableField("settlement")
     private Integer settlement;

+ 8 - 0
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/LogisticListReq.java

@@ -135,6 +135,14 @@ public class LogisticListReq implements Serializable {
         @Schema(description = "派车方式 1-手动派车,2-自动派车")
         private Integer dispatchWay = 1;
 
+
+        /**
+         * 结算方式 (1普通结算,2预付制结算)
+         */
+        @NotNull(message = "结算方式不能为空")
+        @Schema(description = "结算方式 (1普通结算,2记账模式)")
+        private Integer settlement;
+
         /**
          * 生效时间
          */

+ 2 - 2
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/SupplyContractTradeReq.java

@@ -146,10 +146,10 @@ public class SupplyContractTradeReq implements Serializable {
         private Date startTime;
 
         /**
-         * 结算方式
+         * 结算方式 1-普通结算 2-预付制结算
          */
         @NotNull(message = "结算方式不能为空")
-        @Schema(description = "结算方式")
+        @Schema(description = "结算方式 1-普通结算 2-预付制结算")
         private Integer settlement;
 
         /**

+ 1 - 1
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/TradeBaseInfoReqVo.java

@@ -89,7 +89,7 @@ public class TradeBaseInfoReqVo implements Serializable {
     private Date startTime;
 
     /**
-     * 结算方式
+     * 结算方式 1-普通结算 2-预付制结算
      */
     @NotNull(message = "结算方式不能为空")
     private Integer settlement;

+ 1 - 1
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/res/ContractDetailResp.java

@@ -154,7 +154,7 @@ public class ContractDetailResp implements Serializable {
         private Date startTime;
 
         /**
-         * 结算方式
+         * 结算方式 1-普通结算 2-预付制结算
          */
         @Schema(description = "结算方式")
         private Integer settlement;

+ 32 - 1
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/service/operateService/KwcContractLogisticsService.java

@@ -36,8 +36,11 @@ import com.sckw.core.model.page.PageResult;
 import com.sckw.core.utils.*;
 import com.sckw.core.web.constant.HttpStatus;
 import com.sckw.core.web.context.LoginUserHolder;
+import com.sckw.core.web.response.BaseResult;
 import com.sckw.core.web.response.result.PageDataResult;
 import com.sckw.excel.utils.ExcelUtil;
+import com.sckw.payment.api.feign.PaymentFeignService;
+import com.sckw.payment.api.model.feign.WalletPayableDto;
 import com.sckw.product.api.dubbo.GoodsInfoService;
 import com.sckw.product.api.model.KwpGoods;
 import com.sckw.stream.enums.MessageEnum;
@@ -104,6 +107,10 @@ public class KwcContractLogisticsService {
     @Autowired
     private IKwcContractLogisticsScoreService  logisticsScoreService;
 
+    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
+    @Autowired
+    private PaymentFeignService paymentFeignService;
+
     private final KwcContractLogisticsRepository kwcContractLogisticsRepository;
     private final KwcContractLogisticsUnitRepository kwcContractLogisticsUnitRepository;
     private final KwcContractLogisticsGoodsRepository kwcContractLogisticsGoodsRepository;
@@ -1323,6 +1330,9 @@ public class KwcContractLogisticsService {
         KwcContractLogistics saveContractLogistics = new KwcContractLogistics();
         Date date = new Date();
         LogisticListReq.TradeBaseInfo baseInfo = req.getBaseInfo();
+        if(Objects.equals(baseInfo.getSettlement(),1)){
+            throw new BusinessException("暂不支持普通结算模式");
+        }
         if (Objects.nonNull(req.getId())){
             saveContractLogistics.setId(req.getId());
         }else {
@@ -1337,6 +1347,7 @@ public class KwcContractLogisticsService {
         saveContractLogistics.setName(baseInfo.getContractName());
         saveContractLogistics.setSigningWay(baseInfo.getSigningWay());
         saveContractLogistics.setDispatchWay(baseInfo.getDispatchWay());
+        saveContractLogistics.setSettlement(baseInfo.getSettlement());
         saveContractLogistics.setStartTime(baseInfo.getStartTime());
         if (Objects.isNull(baseInfo.getEndTime())){
             LocalDate localDate = LocalDate.of(9999, 12, 30);
@@ -1638,6 +1649,7 @@ public class KwcContractLogisticsService {
         return tradeGoodsInfo;
     }
 
+    @Transactional(rollbackFor = Exception.class)
     public Boolean updateLogistics(UpdateLogisticsReq req) {
         log.info("更新物流合同参数:{}", JSON.toJSONString( req));
         KwcContractLogistics logistics = kwcContractLogisticsRepository.queryById(req.getLogContractId());
@@ -1654,7 +1666,26 @@ public class KwcContractLogisticsService {
             updateLogistics.setStatus(req.getLogStatus());
             updateLogistics.setId(logistics.getId());
         }
-       return kwcContractLogisticsRepository.updateLogistics(updateLogistics);
+        Boolean result = kwcContractLogisticsRepository.updateLogistics(updateLogistics);
+        if(Integer.valueOf(ContractStatusEnum.SIGNED.getCode()).equals(updateLogistics.getStatus()) && result){
+            //物流合同签约成功,建立运费清单
+            //查询物流企业信息
+            List<KwcContractLogisticsUnit> kwcContractLogisticsUnits = kwcContractLogisticsUnitRepository.queryByContractIds(Collections.singleton(logistics.getId()));
+            Map<Integer, KwcContractLogisticsUnit> collect = kwcContractLogisticsUnits.stream().collect(Collectors.toMap(KwcContractLogisticsUnit::getUnitType, Function.identity(), (x, y) -> x));
+            WalletPayableDto payableAddDto = new WalletPayableDto();
+            payableAddDto.setConsignEntId(collect.get(CooperateTypeEnum.CONSIGN.getCode()).getEntId());
+            payableAddDto.setCarriageEntId(collect.get(CooperateTypeEnum.CARRIAGE.getCode()).getEntId());
+            payableAddDto.setTradeAmount(BigDecimal.ZERO);
+            payableAddDto.setRemark("运费清单初始化");
+            BaseResult<Object> payable = paymentFeignService.initPayable(payableAddDto);
+            if (payable.getCode() == HttpStatus.SUCCESS_CODE){
+                log.info("创建运费清单成功");
+            }else {
+                log.error("创建运费清单失败");
+                throw new BusinessException("创建运费清单失败");
+            }
+        }
+        return result;
     }
 
     public ContractStatusCountResp queryLogisticContractStatusCount( QueryLogisticListReq req) {

+ 31 - 1
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/service/operateService/KwcContractTradeService.java

@@ -40,11 +40,14 @@ import com.sckw.core.model.page.PageResult;
 import com.sckw.core.utils.*;
 import com.sckw.core.web.constant.HttpStatus;
 import com.sckw.core.web.context.LoginUserHolder;
+import com.sckw.core.web.response.BaseResult;
 import com.sckw.core.web.response.result.PageDataResult;
 import com.sckw.excel.utils.ExcelUtil;
 import com.sckw.order.api.dubbo.TradeOrderInfoService;
 import com.sckw.order.api.model.ContractSignCompletedParam;
 import com.sckw.order.api.model.TradeOrderContractVo;
+import com.sckw.payment.api.feign.PaymentFeignService;
+import com.sckw.payment.api.model.feign.WalletPrepaidDto;
 import com.sckw.product.api.dubbo.GoodsInfoService;
 import com.sckw.product.api.model.KwpGoods;
 import com.sckw.stream.enums.MessageEnum;
@@ -129,6 +132,8 @@ public class KwcContractTradeService {
     private TradeOrderInfoService tradeOrderInfoService;
     @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 8000)
     private TransportRemoteService transportRemoteService;
+    @Autowired
+    private PaymentFeignService paymentFeignService;
 
     /**
      * 销售合同
@@ -358,6 +363,9 @@ public class KwcContractTradeService {
             if (Objects.equals(baseInfo.getUnloadWay(), Integer.parseInt(DictEnum.LOAD_UNLOAD_WAY_2.getValue())) && Objects.isNull(baseInfo.getMeasurementWay())) {
                 throw new SystemException("卸货方式为按卸货筽量时,计量方式不能为空!");
             }
+            if(Objects.equals(baseInfo.getSettlement(),1)){
+                throw new SystemException("暂不支持普通结算模式!");
+            }
         }
 
         if (CollectionUtils.isNotEmpty(goodsInfo)) {
@@ -1406,6 +1414,9 @@ public class KwcContractTradeService {
             if (StringUtils.isNotBlank(baseInfo.getContractName()) && baseInfo.getContractName().length() > 20) {
                 throw new SystemException("合同名称超长!");
             }
+            if(Objects.equals(baseInfo.getSettlement(),1)){
+                throw new SystemException("暂不支持普通结算模式!");
+            }
         }
 
         if (Objects.equals(DispatchWayEnums.MANUAL_DISPATCH.getCode(), baseInfo.getDispatchWay())) {
@@ -1470,7 +1481,26 @@ public class KwcContractTradeService {
                 ContractStatusEnum.SIGNED.getCode())) {
             updateKwcContractTrade.setStatus(ContractStatusEnum.COMPLETE.getCode());
         }
-        return kwcContractTradeRepository.updateByContractId(updateKwcContractTrade);
+        Boolean result = kwcContractTradeRepository.updateByContractId(updateKwcContractTrade);
+        if(Objects.equals(req.getStatus(), ContractStatusEnum.SIGNED.getCode()) && Objects.equals(updateKwcContractTrade.getStatus(),ContractStatusEnum.SIGNED.getCode())){
+            //签约成功,初始化预付清单
+            //根据订单号查询交易企业信息
+            List<KwcContractTradeUnit> tradeUnits = kwcContractTradeUnitRepository.queryByContractId(kwcContractTrade.getId());
+            Map<Integer, KwcContractTradeUnit> collect = tradeUnits.stream().collect(Collectors.toMap(KwcContractTradeUnit::getUnitType, Function.identity(), (x, y) -> x));
+            WalletPrepaidDto prepaidDto = new WalletPrepaidDto();
+            prepaidDto.setProEntId(collect.get(CooperateTypeEnum.PURCHASER.getCode()).getEntId());
+            prepaidDto.setSupEntId(collect.get(CooperateTypeEnum.SUPPLIER.getCode()).getEntId());
+            prepaidDto.setTradeAmount(BigDecimal.ZERO);
+            prepaidDto.setRemark("预付清单初始化");
+            BaseResult<Object> prepaidResult = paymentFeignService.initPrepaidBalance(prepaidDto);
+            if (prepaidResult.getCode() == HttpStatus.SUCCESS_CODE){
+                log.info("创建预付清单成功");
+            }else {
+                log.error("创建预付清单失败");
+                throw new BusinessException("创建预付清单失败");
+            }
+        }
+        return result;
 
     }
 

+ 1 - 1
sckw-modules/sckw-contract/src/main/resources/bootstrap-test.yml

@@ -5,7 +5,7 @@ spring:
         # 服务注册地址
         server-addr: @nacos.server@
         # 命名空间
-        namespace: @nacos.namespace@
+        namespace: sckw-ng-service-platform-dev-tys
         # 共享配置
         group: sckw-ng-service-platform
       config:

+ 1 - 1
sckw-modules/sckw-file/src/main/resources/bootstrap-test.yml

@@ -5,7 +5,7 @@ spring:
         # 服务注册地址
         server-addr: @nacos.server@
         # 命名空间
-        namespace: @nacos.namespace@
+        namespace: sckw-ng-service-platform-dev-tys
         # 共享配置
         group: sckw-ng-service-platform
       config:

+ 33 - 0
sckw-modules/sckw-order/src/main/java/com/sckw/order/config/FeignConfig.java

@@ -0,0 +1,33 @@
+package com.sckw.order.config;
+
+
+import com.sckw.core.model.constant.Global;
+import feign.RequestInterceptor;
+import jakarta.servlet.http.HttpServletRequest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+
+/**
+ * @Author: tangyishan
+ * @CreateTime: 2025-12-12  16:10
+ * @Description: feign远程调用配置
+ */
+@Configuration
+public class FeignConfig {
+
+    @Bean
+    public RequestInterceptor requestInterceptor() {
+        return requestTemplate -> {
+            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+            HttpServletRequest request = attributes.getRequest();
+            String userInfoStrEncode = request.getHeader(Global.USER_INFO_STR_ENCODE);
+            String entInfoStrEncode = request.getHeader(Global.ENT_INFO_STR_ENCODE);
+            requestTemplate.header(Global.USER_INFO_STR_ENCODE, userInfoStrEncode);
+            requestTemplate.header(Global.ENT_INFO_STR_ENCODE, entInfoStrEncode);
+        };
+    }
+
+}

+ 11 - 0
sckw-modules/sckw-order/src/main/java/com/sckw/order/model/KwoTradeOrder.java

@@ -58,6 +58,11 @@ public class KwoTradeOrder extends BaseModel implements Serializable {
      */
     private BigDecimal price;
 
+    /**
+     * 状态:0正常(未绑定)/1锁定(绑定)
+     */
+    private Integer status;
+
     /**
      * 签约方式 1线上  2线下
      */
@@ -129,6 +134,12 @@ public class KwoTradeOrder extends BaseModel implements Serializable {
     @TableField("dispatch_way")
     private Integer dispatchWay;
 
+    /**
+     * 结算方式 1普通结算,2预付制结算
+     */
+    @TableField("settlement")
+    private Integer settlement;
+
     /**
      * 是否需要增派运力(0-否,1-是)
      */

+ 133 - 100
sckw-modules/sckw-order/src/main/java/com/sckw/order/serivce/KwoTradeOrderService.java

@@ -56,12 +56,12 @@ import com.sckw.order.model.vo.res.UnitInfoDetailRes;
 import com.sckw.order.repository.KwoTradeOrderUnitRepository;
 import com.sckw.payment.api.dubbo.PayCenterDubboService;
 import com.sckw.payment.api.dubbo.PaymentDubboService;
-import com.sckw.payment.api.feign.OfflineWalletFeignService;
 import com.sckw.payment.api.model.WalletFreeze;
+import com.sckw.payment.api.feign.PaymentFeignService;
 import com.sckw.payment.api.model.constant.ChannelEnum;
 import com.sckw.payment.api.model.dto.WalletDto;
-import com.sckw.payment.api.model.dto.WalletFreezeDto;
 import com.sckw.payment.api.model.dto.common.R;
+import com.sckw.payment.api.model.feign.WalletPrepaidDto;
 import com.sckw.product.api.dubbo.GoodsInfoService;
 import com.sckw.product.api.model.AddressInfoDetail;
 import com.sckw.product.api.model.GoodsDetail;
@@ -140,8 +140,8 @@ public class KwoTradeOrderService {
     @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
     protected RemoteFleetService remoteFleetService;
 
-    @Autowired(required = false)
-    private OfflineWalletFeignService offlineWalletFeignService;
+    @Autowired
+    private PaymentFeignService paymentFeignService;
 
     private final KwoTradeOrderMapper kwoTradeOrderMapper;
     private final StreamBridge streamBridge;
@@ -2082,8 +2082,6 @@ public class KwoTradeOrderService {
         TradeContractResDto tradeContractResDto = checkPara(tradeOrderParam, order, goodsById);
 
         // ====== 下单前校验 start ======
-        // 1. 验证线下钱包预付余额是否足够,不足则提示"线下钱包预付余额不足"
-        checkWallet(order);
 
         // 2. 验证商品是否开启库存(amount不为null代表已开启库存,null代表无限库存无需验证)
         if (goodsById.getAmount() != null && goodsById.getAmount().compareTo(tradeOrderParam.getAmount()) < 0) {
@@ -2092,10 +2090,6 @@ public class KwoTradeOrderService {
             }
         }
 
-        // 4. 记录钱包金额账数据,类型为冻结,备注为"贸易订单号:xxx 下单冻结"
-        // TODO: 后续对接外部系统,记录钱包流水
-        // recordWalletTransaction(buyEntId, order.getPrice(), "冻结", "贸易订单号:" + order.getTOrderNo() + " 下单冻结");
-
         // 5. 验证贸易合同限量采购,若为限量采购则校验剩余可采购数量并扣减本次下单量
         GoodsInfoDto contractGoodsInfo = tradeContractResDto.getGoodsInfoDto();
         if (contractGoodsInfo.getAmount() != null && contractGoodsInfo.getAmount().compareTo(BigDecimal.ZERO) > 0) {
@@ -2108,17 +2102,14 @@ public class KwoTradeOrderService {
         }
         // ====== 下单前校验 end ======
 
-        WalletFreeze walletFreeze = new WalletFreeze();
-        walletFreeze.setOrderNo(order.getTOrderNo());
-        walletFreeze.setMoney(order.getPrice());
-
         //商品地址信息
         AddressInfoDetail goodsAddress = goodsInfoService.getGoodsAddress(tradeOrderParam.getGoodsId());
         if (Objects.isNull(goodsAddress)) {
             throw new BusinessException("商品发货地址信息不存在");
         }
+        order.setSettlement(tradeContractResDto.getSettlement());
         kwoTradeOrderMapper.insert(order);//贸易订单
-        walletFreeze.setTTradeOrderId(order.getId());
+//        walletFreeze.setTTradeOrderId(order.getId());
 
         GoodsInfoDto goodsInfoDto = tradeContractResDto.getGoodsInfoDto();//贸易合同,下合同关联的商品信息
         KwoTradeOrderGoods kwoTradeOrderGoods = new KwoTradeOrderGoods();
@@ -2222,74 +2213,42 @@ public class KwoTradeOrderService {
             }
         }
         List<TradeContractUnitDto> unitList = tradeContractResDto.getUnitList();
-        WalletFreezeDto freezeDto = new WalletFreezeDto();
         List<KwoTradeOrderUnit> list = new ArrayList<>();
+        WalletPrepaidDto walletFreeze = new WalletPrepaidDto();
+        walletFreeze.setOrderNo(String.valueOf(order.getId()));
+        walletFreeze.setTradeAmount(order.getPrice());
         unitList.forEach(e -> {
             KwoTradeOrderUnit unit = BeanUtil.copyProperties(e, KwoTradeOrderUnit.class);
             unit.setId(new IdWorker(1).nextId());
             unit.setTOrderId(order.getId()).setTOrderNo(order.getTOrderNo()).setTopEntId(e.getEntId());
             unit.setUnitType(StrUtil.equals(e.getUnitType(), "1") ? "2" : "1");//贸易合同和订单的单位类型相反
             if (StrUtil.equals(unit.getUnitType(), "1")) {
-                walletFreeze.setBuyEntId(unit.getEntId());
-                freezeDto.setProEntId(unit.getEntId());
+//                walletFreeze.setBuyEntId(unit.getEntId());
+                walletFreeze.setProEntId(unit.getEntId());
             }
             if (StrUtil.equals(unit.getUnitType(), "2")) {
-                walletFreeze.setSaleEntId(unit.getEntId());
-                freezeDto.setSupEntId(unit.getEntId());
+//                walletFreeze.setSaleEntId(unit.getEntId());
+                walletFreeze.setSupEntId(unit.getEntId());
             }
             list.add(unit);
         });
         kwoTradeOrderUnitService.insertBatch(list);
         //钱包
-        BaseResult<Boolean> booleanBaseResult = paymentDubboService.freezeMoney(walletFreeze);
-        if (booleanBaseResult.getCode() != 60200) {
-            throw new BusinessException(booleanBaseResult.getMessage());
-        }
-        // 3. 线下钱包扣减预付余额、增加冻结金额
-        walletFreeze(tradeOrderParam, order,freezeDto);
-    }
+//        BaseResult<Boolean> booleanBaseResult = paymentDubboService.freezeMoney(walletFreeze);
+        BaseResult<Object> freezeBaseResult = new  BaseResult<>();
+        if(Objects.equals(tradeContractResDto.getSettlement(),1)){
+            // todo 普通结算冻结
 
-    private void walletFreeze(TradeOrderParam tradeOrderParam, KwoTradeOrder order,WalletFreezeDto freezeDto) {
-        if (offlineWalletFeignService == null) {
-            throw new BusinessException("线下钱包服务未配置,无法执行冻结操作");
+        }else if(Objects.equals(tradeContractResDto.getSettlement(),2)){
+            //预付制结算冻结
+            walletFreeze.setOrderType(4);
+            walletFreeze.setTradeType(4);
+            walletFreeze.setRemark("贸易订单号:"+walletFreeze.getOrderNo()+",下单冻结");
+            freezeBaseResult = paymentFeignService.updatePrepaidBalance(walletFreeze);
         }
 
-        freezeDto.setFreezeAmount(tradeOrderParam.getAmount());
-        freezeDto.setOrderNo(order.getTOrderNo());
-
-        BaseResult<Boolean> balanceResult;
-        try {
-            balanceResult = offlineWalletFeignService.freezeBalance(freezeDto);
-        } catch (Exception e) {
-            log.error("线下钱包扣减预付余额、增加冻结金额异常", e);
-            throw new BusinessException("线下钱包扣减预付余额、增加冻结金额异常");
-        }
-        if (balanceResult == null || balanceResult.getCode() != HttpStatus.SUCCESS_CODE) {
-            throw new BusinessException("线下钱包扣减预付余额、增加冻结金额失败");
-        }
-        Boolean aBoolean = balanceResult.getData();
-        if (!Boolean.TRUE.equals(aBoolean)) {
-            throw new BusinessException("线下钱包扣减预付余额、增加冻结金额失败");
-        }
-    }
-
-    private void checkWallet(KwoTradeOrder order) {
-        if (offlineWalletFeignService == null) {
-            throw new BusinessException("线下钱包服务未配置,无法查询余额");
-        }
-        BaseResult<BigDecimal> balanceResult;
-        try {
-            balanceResult = offlineWalletFeignService.queryPrepaidBalance(LoginUserHolder.getEntId());
-        } catch (Exception e) {
-            log.error("查询线下钱包服务异常", e);
-            throw new BusinessException("查询线下钱包服务异常,请稍后再试");
-        }
-        if (balanceResult == null || balanceResult.getCode() != HttpStatus.SUCCESS_CODE) {
-            throw new BusinessException("查询线下钱包预付余额失败,请稍后再试");
-        }
-        BigDecimal prepaidBalance = balanceResult.getData();
-        if (prepaidBalance == null || prepaidBalance.compareTo(order.getPrice()) < 0) {
-            throw new BusinessException("线下钱包预付余额不足");
+        if (freezeBaseResult.getCode() != 60200) {
+            throw new BusinessException(freezeBaseResult.getMessage());
         }
     }
 
@@ -2311,7 +2270,7 @@ public class KwoTradeOrderService {
         TradeContractResDto tradeContractResDto = remoteContractService.queryTradeContract(param.getTradeContractId(), param.getGoodsId());
         // 1. 线下钱包加回预付余额、减冻结金额
         List<TradeContractUnitDto> unitList = tradeContractResDto.getUnitList();
-        WalletFreezeDto freezeDto = new WalletFreezeDto();
+        WalletPrepaidDto freezeDto = new WalletPrepaidDto();
         unitList.forEach(e -> {
             KwoTradeOrderUnit unit = BeanUtil.copyProperties(e, KwoTradeOrderUnit.class);
             unit.setId(new IdWorker(1).nextId());
@@ -2324,15 +2283,13 @@ public class KwoTradeOrderService {
                 freezeDto.setSupEntId(unit.getEntId());
             }
         });
-         freezeDto.setFreezeAmount(param.getFreezeAmount());
-         freezeDto.setOrderNo(order.getTOrderNo());
-
-        if (offlineWalletFeignService == null) {
-            throw new BusinessException("线下钱包服务未配置,无法执行解冻操作");
-        }
-        BaseResult<Boolean> balanceResult;
+        freezeDto.setOrderNo(String.valueOf(order.getId()));
+        freezeDto.setOrderType(4);
+        freezeDto.setTradeType(5);
+        freezeDto.setRemark("贸易订单号:"+freezeDto.getOrderNo()+",撤销订单");
+        BaseResult<Object> balanceResult;
         try {
-            balanceResult = offlineWalletFeignService.unfreezeBalance(freezeDto);
+            balanceResult = paymentFeignService.updatePrepaidBalance(freezeDto);
         } catch (Exception e) {
             log.error("线下钱包扣减预付余额、增加冻结金额异常", e);
             throw new BusinessException("线下钱包扣减预付余额、增加冻结金额异常");
@@ -2340,24 +2297,11 @@ public class KwoTradeOrderService {
         if (balanceResult == null || balanceResult.getCode() != HttpStatus.SUCCESS_CODE) {
             throw new BusinessException("线下钱包扣减预付余额、增加冻结金额失败");
         }
-        Boolean aBoolean = balanceResult.getData();
+        Boolean aBoolean = (Boolean) balanceResult.getData();
         if (!Boolean.TRUE.equals(aBoolean)) {
             throw new BusinessException("线下钱包扣减预付余额、增加冻结金额失败");
         }
 
-        // 2. 记录钱包金额账数据,类型为解冻,备注为"贸易订单号:xxx 撤销订单"
-        // TODO: 后续对接外部系统,记录钱包流水
-        // recordWalletTransaction(buyEntId, order.getPrice(), "解冻", "贸易订单号:" + order.getTOrderNo() + " 撤销订单");
-
-        // 线上钱包解冻
-        WalletFreeze walletFreeze = new WalletFreeze();
-        walletFreeze.setTTradeOrderId(order.getId());
-        walletFreeze.setOrderNo(order.getTOrderNo());
-        BaseResult<Boolean> unfreezeResult = paymentDubboService.unfreezeMoney(walletFreeze);
-        if (unfreezeResult.getCode() != 60200) {
-            throw new BusinessException(unfreezeResult.getMessage());
-        }
-
         // 3. 贸易合同该商品有采购数量,则更新采购数量(加回本单总量)
         KwoTradeOrderGoods orderGoods = kwoTradeOrderGoodsService.getByOrderId(order.getId());
         KwoTradeOrderContract orderContract = kwoTradeOrderContractService.getByOrderId(order.getId());
@@ -2397,12 +2341,36 @@ public class KwoTradeOrderService {
         if (Objects.isNull(goodsInfoDto)) {
             throw new BusinessException("当前贸易订单不存在交易商品");
         }
+
+        //结算方式校验余额
+        BigDecimal orderAmount = NumberUtil.mul(tradeOrderParam.getAmount(), goodsInfoDto.getPrice());
+        Integer settlement = tradeContractResDto.getSettlement();
+        if(Objects.equals(settlement, 1)){
+            // todo 普通结算
+
+        }else {
+            //预付制结算
+            BaseResult<BigDecimal> prepaidBalanceResult = null;
+            try {
+                prepaidBalanceResult = paymentFeignService.queryPrepaidBalance(goodsById.getSupplyEntId());
+            } catch (Exception e) {
+                log.error("查询线下钱包服务异常", e);
+                throw new BusinessException("查询线下钱包服务异常,请稍后再试");
+            }
+            if(prepaidBalanceResult.getCode() == HttpStatus.SUCCESS_CODE){
+                if(orderAmount.compareTo(prepaidBalanceResult.getData()) > 0){
+                    throw new BusinessException("当前贸易订单金额大于可用预付余额");
+                }
+            }else{
+                throw new BusinessException("查询对应供应商预付余额失败");
+            }
+        }
         tradeOrderParam.setTradeContractNo(tradeContractResDto.getContractNo());
         order.setUnit(goodsById.getUnit());
         order.setPickupType(String.valueOf(tradeContractResDto.getConsignment()));//来源于合同约束的托运方式
         order.setDeliveryType("");
         order.setTrading(String.valueOf(tradeContractResDto.getSigningWay()));//签约方式
-        order.setPrice(NumberUtil.mul(tradeOrderParam.getAmount(), goodsInfoDto.getPrice()));//总金额
+        order.setPrice(orderAmount);//总金额
         order.setActualAmount(new BigDecimal("0"));
         order.setAssociateStatement(0);
         order.setLoadAmount(new BigDecimal("0"));
@@ -2452,10 +2420,24 @@ public class KwoTradeOrderService {
 
         if (Objects.equals(tradeOrderAuditParam.getStatus(), 2)) {
             //钱包退回金额
-            WalletFreeze walletFreeze = new WalletFreeze();
-            walletFreeze.setTTradeOrderId(kwoTradeOrder.getId());
-            walletFreeze.setOrderNo(kwoTradeOrder.getTOrderNo());
-            BaseResult<Boolean> booleanBaseResult = paymentDubboService.unfreezeMoney(walletFreeze);
+            WalletPrepaidDto walletFreeze = new WalletPrepaidDto();
+//            walletFreeze.setTTradeOrderId(kwoTradeOrder.getId());
+            walletFreeze.setOrderNo(String.valueOf(kwoTradeOrder.getId()));
+            walletFreeze.setProEntId(unitMap.get(String.valueOf(CooperateTypeEnum.PURCHASER.getCode())).getEntId());
+            walletFreeze.setSupEntId(unitMap.get(String.valueOf(CooperateTypeEnum.SUPPLIER.getCode())).getEntId());
+            walletFreeze.setOrderType(4);
+            walletFreeze.setTradeType(5);
+            walletFreeze.setRemark("贸易订单:"+walletFreeze.getOrderNo()+",审核拒绝解冻");
+//            BaseResult<Boolean> booleanBaseResult = paymentDubboService.unfreezeMoney(walletFreeze);
+
+            BaseResult<Object> booleanBaseResult = new  BaseResult<>();
+            if(Objects.equals(kwoTradeOrder.getSettlement(),1)){
+                // todo 普通结算解冻结
+
+            }else if(Objects.equals(kwoTradeOrder.getSettlement(),2)){
+                //预付制结算解冻
+                booleanBaseResult = paymentFeignService.updatePrepaidBalance(walletFreeze);
+            }
             if (booleanBaseResult.getCode() != 60200) {
                 throw new BusinessException(booleanBaseResult.getMessage());
             }
@@ -2558,8 +2540,8 @@ public class KwoTradeOrderService {
                 logisticInfo.setAcceptCompany("");
                 logisticInfo.setPrice(d.getTransportPrice());
                 logisticInfo.setPriceType(0L);
-                logisticInfo.setAmount(new BigDecimal("0"));
-                logisticInfo.setAmountUnit("");
+                logisticInfo.setAmount(kwoTradeOrder.getAmount());
+                logisticInfo.setAmountUnit(kwoTradeOrder.getUnit());
                 logisticInfo.setLoss(new BigDecimal("0"));
                 logisticInfo.setPayment(0L);
                 logisticInfo.setSigningWay(0);
@@ -2589,8 +2571,8 @@ public class KwoTradeOrderService {
                 logisticInfo.setAcceptCompany("");
                 logisticInfo.setPrice(d.getTransportPrice());
                 logisticInfo.setPriceType(0L);
-                logisticInfo.setAmount(new BigDecimal("0"));
-                logisticInfo.setAmountUnit("");
+                logisticInfo.setAmount(kwoTradeOrder.getAmount());
+                logisticInfo.setAmountUnit(kwoTradeOrder.getUnit());
                 logisticInfo.setLoss(new BigDecimal("0"));
                 logisticInfo.setPayment(0L);
                 logisticInfo.setSigningWay(0);
@@ -2618,8 +2600,8 @@ public class KwoTradeOrderService {
                     logisticInfo.setAcceptCompany(d.getFirmName());
                     logisticInfo.setPrice(d.getTransportPrice());
                     logisticInfo.setPriceType(0L);
-                    logisticInfo.setAmount(new BigDecimal("0"));
-                    logisticInfo.setAmountUnit("");
+                    logisticInfo.setAmount(kwoTradeOrder.getAmount());
+                    logisticInfo.setAmountUnit(kwoTradeOrder.getUnit());
                     logisticInfo.setLoss(new BigDecimal("0"));
                     logisticInfo.setPayment(0L);
                     logisticInfo.setSigningWay(0);
@@ -2798,6 +2780,7 @@ public class KwoTradeOrderService {
      */
     public Object settleOrder(TradeOrderSettleParam tradeOrderSettleParam) {
         KwoTradeOrder kwoTradeOrder = new KwoTradeOrder();
+        KwoTradeOrder kwoTradeOrderDB = kwoTradeOrderMapper.selectOne(new LambdaQueryWrapper<KwoTradeOrder>().eq(KwoTradeOrder::getId, tradeOrderSettleParam.getId()).eq(KwoTradeOrder::getDelFlag, 0));
         List<KwtLogisticsOrderVO> logisticOrderList = transportRemoteService.getLogisticOrderList(new OrderFinishParam(tradeOrderSettleParam.getId()));
         if (CollUtil.isNotEmpty(logisticOrderList)) {
             if (logisticOrderList.stream().allMatch(d -> Objects.equals(d.getStatus(), LogisticsOrderV1Enum.NEARING_COMPLETION.getCode()))) {
@@ -2821,9 +2804,59 @@ public class KwoTradeOrderService {
             }
         }
         kwoTradeOrderMapper.updateById(kwoTradeOrder);
+        calculatePrepaidBalance(kwoTradeOrderDB);
         return true;
     }
 
+    private void calculatePrepaidBalance(KwoTradeOrder kwoTradeOrder){
+        if(Objects.equals(kwoTradeOrder.getStatus(),TradeOrderStatusEnum.SUCCESS.getCode())){
+            //贸易订单已完结,计算预付余额
+            if(Objects.equals(kwoTradeOrder.getSettlement(),1)){
+                //todo 普通结算
+
+            }else if(Objects.equals(kwoTradeOrder.getSettlement(),2)){
+                //预付制模式
+                //1解冻运费
+                List<KwoTradeOrderUnit> orderUnits = kwoTradeOrderUnitService.getByOrderId(kwoTradeOrder.getId());
+                if (CollUtil.isEmpty(orderUnits)) {
+                    throw new BusinessException("贸易订单企业信息不存在");
+                }
+                Map<String, KwoTradeOrderUnit> unitMap = orderUnits.stream().collect(Collectors.toMap(KwoTradeOrderUnit::getUnitType, e -> e, (a, b) -> a));
+                if (unitMap.keySet().size() < 2) {
+                    throw new BusinessException("贸易订单企业信息缺失");
+                }
+                //钱包退回金额
+                WalletPrepaidDto unFreezePrepaidDto = new WalletPrepaidDto();
+                unFreezePrepaidDto.setOrderNo(String.valueOf(kwoTradeOrder.getId()));
+                unFreezePrepaidDto.setProEntId(unitMap.get(String.valueOf(CooperateTypeEnum.PURCHASER.getCode())).getEntId());
+                unFreezePrepaidDto.setSupEntId(unitMap.get(String.valueOf(CooperateTypeEnum.SUPPLIER.getCode())).getEntId());
+                unFreezePrepaidDto.setOrderType(4);
+                unFreezePrepaidDto.setTradeType(5);
+                unFreezePrepaidDto.setRemark("贸易订单:"+unFreezePrepaidDto.getOrderNo()+",");
+                BaseResult<Object> unFreezeResult = paymentFeignService.updatePrepaidBalance(unFreezePrepaidDto);
+                if(unFreezeResult.getCode()!= HttpStatus.SUCCESS_CODE){
+                    log.error("贸易订单号:{},订单完结解冻失败,异常信息为:{}",unFreezePrepaidDto.getOrderNo(),unFreezeResult.getMessage());
+                    throw new BusinessException("贸易订单号:"+unFreezePrepaidDto.getOrderNo()+",订单完结解冻失败");
+                }
+                //2计算订单金额
+                WalletPrepaidDto consumePrepaidDto = new WalletPrepaidDto();
+                unFreezePrepaidDto.setOrderNo(String.valueOf(kwoTradeOrder.getId()));
+                unFreezePrepaidDto.setProEntId(unitMap.get(String.valueOf(CooperateTypeEnum.PURCHASER.getCode())).getEntId());
+                unFreezePrepaidDto.setSupEntId(unitMap.get(String.valueOf(CooperateTypeEnum.SUPPLIER.getCode())).getEntId());
+                unFreezePrepaidDto.setOrderType(4);
+                unFreezePrepaidDto.setTradeType(6);
+                consumePrepaidDto.setTradeAmount(kwoTradeOrder.getPrice());
+                consumePrepaidDto.setRemark("贸易订单号:"+consumePrepaidDto.getOrderNo()+",订单完结消费");
+                BaseResult<Object> consumeResult = paymentFeignService.updatePrepaidBalance(consumePrepaidDto);
+                if(consumeResult.getCode()!= HttpStatus.SUCCESS_CODE){
+                    log.error("贸易订单号:{},订单完结消费失败,异常信息为:{}",consumePrepaidDto.getOrderNo(),consumeResult.getMessage());
+                    throw new BusinessException("贸易订单号:"+consumePrepaidDto.getOrderNo()+",订单完结消费失败");
+                }
+            }
+        }
+
+    }
+
     public void updateOrderAmount(TradeOrderSettlePara tradeOrderSettlePara) {
         if (Objects.isNull(tradeOrderSettlePara.getTOrderId())) {
             throw new BusinessException("订单id不能为空");

+ 110 - 25
sckw-modules/sckw-order/src/main/java/com/sckw/order/task/TradeOrderTask.java

@@ -2,11 +2,13 @@ package com.sckw.order.task;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.NumberUtil;
-import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.sckw.core.exception.BusinessException;
 import com.sckw.core.model.constant.Global;
+import com.sckw.core.model.enums.CooperateTypeEnum;
 import com.sckw.core.model.enums.LogisticsOrderV1Enum;
 import com.sckw.core.utils.DateUtils;
+import com.sckw.core.web.constant.HttpStatus;
 import com.sckw.core.web.response.BaseResult;
 import com.sckw.order.dao.KwoTradeOrderGoodsMapper;
 import com.sckw.order.dao.KwoTradeOrderMapper;
@@ -16,13 +18,15 @@ import com.sckw.order.model.KwoTradeOrder;
 import com.sckw.order.model.KwoTradeOrderGoods;
 import com.sckw.order.model.KwoTradeOrderUnit;
 import com.sckw.payment.api.dubbo.PaymentDubboService;
-import com.sckw.payment.api.model.WalletFreeze;
+import com.sckw.payment.api.feign.PaymentFeignService;
+import com.sckw.payment.api.model.feign.WalletPrepaidDto;
 import com.sckw.transport.api.dubbo.TransportRemoteService;
 import com.sckw.transport.api.model.param.OrderFinishParam;
 import com.sckw.transport.api.model.vo.KwtLogisticsOrderVO;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboReference;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
@@ -51,6 +55,9 @@ public class TradeOrderTask {
     private TransportRemoteService transportRemoteService;
     @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 8000)
     private PaymentDubboService paymentDubboService;
+
+    @Autowired
+    private PaymentFeignService paymentFeignService;
     private final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 2, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(20));
 
     @Scheduled(cron = "0 0/5 * * * ?")
@@ -85,18 +92,20 @@ public class TradeOrderTask {
                             );
 
                             //更新贸易订单状态
-                            WalletFreeze walletFreeze = new WalletFreeze();
-                            walletFreeze.setBuyEntId(unitMap.getOrDefault("1", new KwoTradeOrderUnit()).getEntId());
-                            walletFreeze.setSaleEntId(unitMap.getOrDefault("2", new KwoTradeOrderUnit()).getEntId());
-                            walletFreeze.setMoney(NumberUtil.mul(sum, kwoTradeOrderGoods.getUnitPrice()));
-                            walletFreeze.setTTradeOrderId(kwoTradeOrder.getId());
-                            walletFreeze.setOrderNo(kwoTradeOrder.getTOrderNo());
-                            log.info("结算 {}", JSONObject.toJSONString(walletFreeze));
-                            BaseResult<Boolean> booleanBaseResult = paymentDubboService.dealMoney(walletFreeze);
-                            log.info("结算结果:{}", JSONObject.toJSONString(booleanBaseResult));
+//                            WalletFreeze walletFreeze = new WalletFreeze();
+//                            walletFreeze.setBuyEntId(unitMap.getOrDefault("1", new KwoTradeOrderUnit()).getEntId());
+//                            walletFreeze.setSaleEntId(unitMap.getOrDefault("2", new KwoTradeOrderUnit()).getEntId());
+//                            walletFreeze.setMoney(NumberUtil.mul(sum, kwoTradeOrderGoods.getUnitPrice()));
+//                            walletFreeze.setTTradeOrderId(kwoTradeOrder.getId());
+//                            walletFreeze.setOrderNo(kwoTradeOrder.getTOrderNo());
+//                            log.info("结算 {}", JSONObject.toJSONString(walletFreeze));
+//                            BaseResult<Boolean> booleanBaseResult = paymentDubboService.dealMoney(walletFreeze);
+//                            log.info("结算结果:{}", JSONObject.toJSONString(booleanBaseResult));
 
                             kwoTradeOrder.setStatus(TradeOrderStatusEnum.SUCCESS.getCode());
                             kwoTradeOrderMapper.updateById(kwoTradeOrder);
+                            kwoTradeOrder.setPrice(NumberUtil.mul(sum, kwoTradeOrderGoods.getUnitPrice()));
+                            calculatePrepaidBalance(kwoTradeOrder,unitMap);
                         } catch (Exception ex) {
                             log.error("更新订单异常{}", ex.getMessage());
                         }
@@ -127,18 +136,20 @@ public class TradeOrderTask {
                                 );
 
                                 //更新贸易订单状态
-                                WalletFreeze walletFreeze = new WalletFreeze();
-                                walletFreeze.setBuyEntId(unitMap.getOrDefault("1", new KwoTradeOrderUnit()).getEntId());
-                                walletFreeze.setSaleEntId(unitMap.getOrDefault("2", new KwoTradeOrderUnit()).getEntId());
-                                walletFreeze.setMoney(NumberUtil.mul(sum, kwoTradeOrderGoods.getUnitPrice()));
-                                walletFreeze.setTTradeOrderId(kwoTradeOrder.getId());
-                                walletFreeze.setOrderNo(kwoTradeOrder.getTOrderNo());
-                                log.info("结算 {}", JSONObject.toJSONString(walletFreeze));
-                                BaseResult<Boolean> booleanBaseResult = paymentDubboService.dealMoney(walletFreeze);
-                                log.info("结算结果:{}", JSONObject.toJSONString(booleanBaseResult));
+//                                WalletFreeze walletFreeze = new WalletFreeze();
+//                                walletFreeze.setBuyEntId(unitMap.getOrDefault("1", new KwoTradeOrderUnit()).getEntId());
+//                                walletFreeze.setSaleEntId(unitMap.getOrDefault("2", new KwoTradeOrderUnit()).getEntId());
+//                                walletFreeze.setMoney(NumberUtil.mul(sum, kwoTradeOrderGoods.getUnitPrice()));
+//                                walletFreeze.setTTradeOrderId(kwoTradeOrder.getId());
+//                                walletFreeze.setOrderNo(kwoTradeOrder.getTOrderNo());
+//                                log.info("结算 {}", JSONObject.toJSONString(walletFreeze));
+//                                BaseResult<Boolean> booleanBaseResult = paymentDubboService.dealMoney(walletFreeze);
+//                                log.info("结算结果:{}", JSONObject.toJSONString(booleanBaseResult));
 
                                 kwoTradeOrder.setStatus(TradeOrderStatusEnum.SUCCESS.getCode());
                                 kwoTradeOrderMapper.updateById(kwoTradeOrder);
+                                kwoTradeOrder.setPrice(NumberUtil.mul(sum, kwoTradeOrderGoods.getUnitPrice()));
+                                calculatePrepaidBalance(kwoTradeOrder,unitMap);
                             } catch (Exception ex) {
                                 log.error("更新订单异常{}", ex.getMessage());
                             }
@@ -165,13 +176,22 @@ public class TradeOrderTask {
                     }
                     if (Objects.equals(one.getKey(), TradeOrderStatusEnum.AUDIT.getCode())) {
                         for (KwoTradeOrder kwoTradeOrder : value) {
-                            WalletFreeze walletFreeze = new WalletFreeze();
-                            walletFreeze.setTTradeOrderId(kwoTradeOrder.getId());
-                            walletFreeze.setOrderNo(kwoTradeOrder.getTOrderNo());
-                            BaseResult<Boolean> booleanBaseResult = paymentDubboService.unfreezeMoney(walletFreeze);
-                            log.info("解冻结果:{}", JSONObject.toJSONString(booleanBaseResult));
+//                            WalletFreeze walletFreeze = new WalletFreeze();
+//                            walletFreeze.setTTradeOrderId(kwoTradeOrder.getId());
+//                            walletFreeze.setOrderNo(kwoTradeOrder.getTOrderNo());
+//                            BaseResult<Boolean> booleanBaseResult = paymentDubboService.unfreezeMoney(walletFreeze);
+//                            log.info("解冻结果:{}", JSONObject.toJSONString(booleanBaseResult));
                             kwoTradeOrder.setStatus(TradeOrderStatusEnum.SUCCESS.getCode());
                             kwoTradeOrderMapper.updateById(kwoTradeOrder);
+                            List<KwoTradeOrderUnit> orderUnits = kwoTradeOrderUnitMapper.selectList(new LambdaQueryWrapper<KwoTradeOrderUnit>().eq(KwoTradeOrderUnit::getTOrderId, kwoTradeOrder.getId())
+                                    .eq(KwoTradeOrderUnit::getDelFlag, 0)
+                            );
+                            if (CollUtil.isEmpty(orderUnits) || orderUnits.size() < 2) {
+                                log.error("订单异常,未找到关联企业。订单id {}", kwoTradeOrder.getId());
+                                return;
+                            }
+                            Map<String, KwoTradeOrderUnit> unitMap = orderUnits.stream().collect(Collectors.toMap(KwoTradeOrderUnit::getUnitType, Function.identity(), (a, b) -> a));
+                            unFreezePrepaid(kwoTradeOrder,unitMap);
                         }
                     }
                     if (Objects.equals(one.getKey(), TradeOrderStatusEnum.ING.getCode())) {
@@ -184,4 +204,69 @@ public class TradeOrderTask {
             });
         }
     }
+
+    private void calculatePrepaidBalance(KwoTradeOrder kwoTradeOrder,Map<String, KwoTradeOrderUnit> unitMap){
+        if(Objects.equals(kwoTradeOrder.getStatus(),TradeOrderStatusEnum.SUCCESS.getCode())){
+            //贸易订单已完结,计算预付余额
+            if(Objects.equals(kwoTradeOrder.getSettlement(),1)){
+                //todo 普通结算
+
+            }else if(Objects.equals(kwoTradeOrder.getSettlement(),2)){
+                //预付制模式
+                //1解冻运费
+                if (unitMap.keySet().size() < 2) {
+                    throw new BusinessException("贸易订单企业信息缺失");
+                }
+                //钱包退回金额
+                WalletPrepaidDto unFreezePrepaidDto = new WalletPrepaidDto();
+                unFreezePrepaidDto.setOrderNo(String.valueOf(kwoTradeOrder.getId()));
+                unFreezePrepaidDto.setProEntId(unitMap.get(String.valueOf(CooperateTypeEnum.PURCHASER.getCode())).getEntId());
+                unFreezePrepaidDto.setSupEntId(unitMap.get(String.valueOf(CooperateTypeEnum.SUPPLIER.getCode())).getEntId());
+                unFreezePrepaidDto.setOrderType(4);
+                unFreezePrepaidDto.setTradeType(5);
+                unFreezePrepaidDto.setRemark("贸易订单:"+unFreezePrepaidDto.getOrderNo()+",");
+                BaseResult<Object> unFreezeResult = paymentFeignService.updatePrepaidBalance(unFreezePrepaidDto);
+                if(unFreezeResult.getCode()!= HttpStatus.SUCCESS_CODE){
+                    log.error("贸易订单号:{},订单完结解冻失败,异常信息为:{}",unFreezePrepaidDto.getOrderNo(),unFreezeResult.getMessage());
+                    throw new BusinessException("贸易订单号:"+unFreezePrepaidDto.getOrderNo()+",订单完结解冻失败");
+                }
+                //2计算订单金额
+                WalletPrepaidDto consumePrepaidDto = new WalletPrepaidDto();
+                unFreezePrepaidDto.setOrderNo(String.valueOf(kwoTradeOrder.getId()));
+                unFreezePrepaidDto.setProEntId(unitMap.get(String.valueOf(CooperateTypeEnum.PURCHASER.getCode())).getEntId());
+                unFreezePrepaidDto.setSupEntId(unitMap.get(String.valueOf(CooperateTypeEnum.SUPPLIER.getCode())).getEntId());
+                unFreezePrepaidDto.setOrderType(4);
+                unFreezePrepaidDto.setTradeType(6);
+                consumePrepaidDto.setTradeAmount(kwoTradeOrder.getPrice());
+                consumePrepaidDto.setRemark("贸易订单号:"+consumePrepaidDto.getOrderNo()+",订单完结消费");
+                BaseResult<Object> consumeResult = paymentFeignService.updatePrepaidBalance(consumePrepaidDto);
+                if(consumeResult.getCode()!= HttpStatus.SUCCESS_CODE){
+                    log.error("贸易订单号:{},订单完结消费失败,异常信息为:{}",consumePrepaidDto.getOrderNo(),consumeResult.getMessage());
+                    throw new BusinessException("贸易订单号:"+consumePrepaidDto.getOrderNo()+",订单完结消费失败");
+                }
+            }
+        }
+
+    }
+
+    private void unFreezePrepaid(KwoTradeOrder kwoTradeOrder,Map<String, KwoTradeOrderUnit> unitMap){
+        //预付制模式
+        //1解冻运费
+        if (unitMap.keySet().size() < 2) {
+            throw new BusinessException("贸易订单企业信息缺失");
+        }
+        //钱包退回金额
+        WalletPrepaidDto unFreezePrepaidDto = new WalletPrepaidDto();
+        unFreezePrepaidDto.setOrderNo(String.valueOf(kwoTradeOrder.getId()));
+        unFreezePrepaidDto.setProEntId(unitMap.get(String.valueOf(CooperateTypeEnum.PURCHASER.getCode())).getEntId());
+        unFreezePrepaidDto.setSupEntId(unitMap.get(String.valueOf(CooperateTypeEnum.SUPPLIER.getCode())).getEntId());
+        unFreezePrepaidDto.setOrderType(4);
+        unFreezePrepaidDto.setTradeType(5);
+        unFreezePrepaidDto.setRemark("贸易订单:"+unFreezePrepaidDto.getOrderNo()+",");
+        BaseResult<Object> unFreezeResult = paymentFeignService.updatePrepaidBalance(unFreezePrepaidDto);
+        if(unFreezeResult.getCode()!= HttpStatus.SUCCESS_CODE){
+            log.error("贸易订单号:{},订单完结解冻失败,异常信息为:{}",unFreezePrepaidDto.getOrderNo(),unFreezeResult.getMessage());
+            throw new BusinessException("贸易订单号:"+unFreezePrepaidDto.getOrderNo()+",订单完结解冻失败");
+        }
+    }
 }

+ 1 - 1
sckw-modules/sckw-order/src/main/resources/mapper/KwoTradeOrderMapper.xml

@@ -712,7 +712,7 @@
 
     <select id="getOrderNumByTopEntId" resultType="com.sckw.order.api.model.TradeOrderCountStatisticsDTO">
         SELECT u.unit_type AS orderType,
-               COUNT(*)    AS num
+               COUNT(0)    AS num
         FROM kwo_trade_order o
                  LEFT JOIN kwo_trade_order_unit u
                            ON o.id = u.t_order_id

+ 1 - 1
sckw-modules/sckw-system/src/main/resources/bootstrap-test.yml

@@ -5,7 +5,7 @@ spring:
         # 服务注册地址
         server-addr: @nacos.server@
         # 命名空间
-        namespace: @nacos.namespace@
+        namespace: sckw-ng-service-platform-dev-tys
         # 共享配置
         group: sckw-ng-service-platform
       config:

+ 6 - 0
sckw-modules/sckw-transport/pom.xml

@@ -153,6 +153,12 @@
             <artifactId>assertj-core</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>com.sckw</groupId>
+            <artifactId>sckw-payment-api</artifactId>
+            <version>${basic.version}</version>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 54 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/UnloadingHandler.java

@@ -4,6 +4,7 @@ package com.sckw.transport.handler;
 import com.alibaba.fastjson2.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.sckw.core.common.enums.enums.ErrorCodeEnum;
+import com.sckw.core.exception.BusinessException;
 import com.sckw.core.exception.BusinessPlatfromException;
 import com.sckw.core.model.constant.Global;
 import com.sckw.core.model.enums.AddressTypeEnum;
@@ -12,12 +13,17 @@ import com.sckw.core.model.enums.LogisticsOrderV1Enum;
 import com.sckw.core.utils.CollectionUtils;
 import com.sckw.core.utils.DateUtils;
 import com.sckw.core.utils.DistanceUtils;
+import com.sckw.core.web.constant.HttpStatus;
+import com.sckw.core.web.response.BaseResult;
 import com.sckw.fleet.api.model.vo.DriverConductRulesVO;
 import com.sckw.fleet.api.model.vo.TruckDispatchCoefficientVO;
 import com.sckw.order.api.model.OrderDetailVo;
 import com.sckw.order.api.model.TradeOrderSettlePara;
+import com.sckw.payment.api.feign.PaymentFeignService;
+import com.sckw.payment.api.model.feign.WalletPayableDto;
 import com.sckw.transport.model.*;
 import com.sckw.transport.model.param.WaybillOrderUnloadParam;
+import com.sckw.transport.repository.KwtLogisticsOrderUnitRepository;
 import com.sckw.transport.repository.KwtWaybillOrderSubtaskRepository;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
@@ -45,6 +51,12 @@ public class UnloadingHandler extends AbstractWaybillOrderHandler<WaybillOrderUn
     @Autowired
     private KwtWaybillOrderSubtaskRepository waybillOrderSubtaskRepository;
 
+    @Autowired
+    private KwtLogisticsOrderUnitRepository kwtLogisticsOrderUnitRepository;
+
+    @Autowired
+    private PaymentFeignService paymentFeignService;
+
     //用于存储动态状态
     private Integer targetStatus;
 
@@ -181,6 +193,48 @@ public class UnloadingHandler extends AbstractWaybillOrderHandler<WaybillOrderUn
             }
         }
         logisticsOrderRepository.updateById(logisticsOrder);
+        if(Objects.equals(logisticsOrder.getStatus(),LogisticsOrderV1Enum.COMPLETED.getCode())){
+            //物流订单已完结,计算待付运费
+            calculateFreight(logisticsOrder);
+        }
+    }
+
+    private void calculateFreight(KwtLogisticsOrder logisticsOrder){
+        if(Objects.equals(logisticsOrder.getSettlement(),1)){
+            //todo 普通结算
+
+        }else if(Objects.equals(logisticsOrder.getSettlement(),2)){
+            //记账模式
+            //1解冻运费
+            List<KwtLogisticsOrderUnit> orderUnits = kwtLogisticsOrderUnitRepository.queryByLOrderId(logisticsOrder.getId());
+            Map<Integer, Long> map = orderUnits.stream().collect(Collectors.toMap(KwtLogisticsOrderUnit::getUnitType, KwtLogisticsOrderUnit::getEntId, (v1, v2) -> v1));
+            WalletPayableDto unFreezePayableDto = new WalletPayableDto();
+            unFreezePayableDto.setConsignEntId(map.get(1));
+            unFreezePayableDto.setCarriageEntId(map.get(2));
+            unFreezePayableDto.setOrderNo(String.valueOf(logisticsOrder.getId()));
+            unFreezePayableDto.setOrderType(5);
+            unFreezePayableDto.setTradeType(5);
+            unFreezePayableDto.setRemark("物流订单号:"+unFreezePayableDto.getOrderNo()+",订单完结解冻");
+            BaseResult<Object> unFreezeResult = paymentFeignService.updatePayable(unFreezePayableDto);
+            if(unFreezeResult.getCode()!= HttpStatus.SUCCESS_CODE){
+                log.error("物流订单号:{},订单完结解冻失败,异常信息为:{}",unFreezePayableDto.getOrderNo(),unFreezeResult.getMessage());
+                throw new BusinessException("物流订单号:"+unFreezePayableDto.getOrderNo()+",订单完结解冻失败");
+            }
+            //2计算待付运费
+            WalletPayableDto consumePayableDto = new WalletPayableDto();
+            consumePayableDto.setConsignEntId(map.get(1));
+            consumePayableDto.setCarriageEntId(map.get(2));
+            consumePayableDto.setOrderNo(String.valueOf(logisticsOrder.getId()));
+            consumePayableDto.setOrderType(5);
+            consumePayableDto.setTradeType(6);
+            consumePayableDto.setTradeAmount(logisticsOrder.getTotalLoadAmount().multiply(logisticsOrder.getPrice()));
+            consumePayableDto.setRemark("物流订单号:"+consumePayableDto.getOrderNo()+",订单完结消费");
+            BaseResult<Object> consumeResult = paymentFeignService.updatePayable(consumePayableDto);
+            if(consumeResult.getCode()!= HttpStatus.SUCCESS_CODE){
+                log.error("物流订单号:{},订单完结消费失败,异常信息为:{}",unFreezePayableDto.getOrderNo(),consumeResult.getMessage());
+                throw new BusinessException("物流订单号:"+unFreezePayableDto.getOrderNo()+",订单完结消费失败");
+            }
+        }
     }
 
     /**

+ 5 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/KwtLogisticsOrder.java

@@ -237,6 +237,11 @@ public class KwtLogisticsOrder implements Serializable {
      * 派单方式(1-手动派单、2-自动派单)
      */
     private Integer dispatchWay;
+
+    /**
+     * 结算方式 (1普通结算,2记账模式)
+     */
+    private Integer settlement;
     /**
      * 装卸货之间的距离
      */

+ 5 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/dto/LogisticData.java

@@ -17,7 +17,12 @@ import java.time.LocalDate;
 public  class LogisticData implements Serializable {
     @Serial
     private static final long serialVersionUID = -4781207406119020652L;
+
     /**
+     * 物流订单id
+     */
+    private Long lOrderId;
+        /**
          * 合同id
          */
         @NotNull(message = "合同id不能为空")

+ 43 - 3
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtAcceptCarriageOrderService.java

@@ -25,6 +25,7 @@ import com.sckw.core.model.page.PageRes;
 import com.sckw.core.utils.*;
 import com.sckw.core.web.constant.HttpStatus;
 import com.sckw.core.web.context.LoginUserHolder;
+import com.sckw.core.web.response.BaseResult;
 import com.sckw.core.web.response.HttpResult;
 import com.sckw.excel.utils.DateUtil;
 import com.sckw.excel.utils.ValidUtil;
@@ -41,7 +42,9 @@ import com.sckw.order.api.dubbo.RemoteTradeOrderAmountService;
 import com.sckw.order.api.dubbo.TradeOrderInfoService;
 import com.sckw.order.api.model.*;
 import com.sckw.payment.api.dubbo.PaymentDubboService;
+import com.sckw.payment.api.feign.PaymentFeignService;
 import com.sckw.payment.api.model.dto.SettlementMoney;
+import com.sckw.payment.api.model.feign.WalletPayableDto;
 import com.sckw.product.api.dubbo.GoodsInfoService;
 import com.sckw.product.api.model.KwpGoods;
 import com.sckw.redis.config.RedisLockUtil;
@@ -123,6 +126,9 @@ public class KwtAcceptCarriageOrderService {
     @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
     PaymentDubboService paymentDubboService;
 
+    @Autowired
+    private PaymentFeignService paymentFeignService;
+
     @Autowired
     public KwtLogisticsOrderGoodsService logisticsOrderGoodsService;
 
@@ -3257,7 +3263,7 @@ public class KwtAcceptCarriageOrderService {
                 dispatched = Math.min(dispatched, actualDisPatch);
 
                 //物流订单信息
-                setLogisticOrderInfo(orderDTO, x, lOrderId, lOrderNo, saveLogisticsOrderList,distance);
+                setLogisticOrderInfo(orderDTO, x, lOrderId, lOrderNo, saveLogisticsOrderList,distance,longContractCommonInfoResDtoMap);
                 //地址信息
                 setLogisticAddress(orderDTO, x, lOrderId, saveAddressList);
                 //商品信息
@@ -3272,7 +3278,7 @@ public class KwtAcceptCarriageOrderService {
 
             } else {
                 //物流订单信息
-                setLogisticOrderInfo(orderDTO, x, lOrderId, lOrderNo, saveLogisticsOrderList,distance);
+                setLogisticOrderInfo(orderDTO, x, lOrderId, lOrderNo, saveLogisticsOrderList,distance,longContractCommonInfoResDtoMap);
 
                 //地址信息
                 setLogisticAddress(orderDTO, x, lOrderId, saveAddressList);
@@ -3290,6 +3296,9 @@ public class KwtAcceptCarriageOrderService {
         // 批量保存并检查结果
         saveBatch(saveLogisticsOrderList, saveAddressList, savelogOrderGoodsList, saveContractList, savelogOrderUnitList, savelogOrderCirculateList);
 
+        //物流订单创建成功,冻结运费
+        freezePayable(orderDTO,logisticInfo,longContractCommonInfoResDtoMap);
+
         //校验派车总量,处理未达标场景
         int unDispatched = actualDisPatch - dispatched;
         if (unDispatched > 0) {
@@ -3300,6 +3309,35 @@ public class KwtAcceptCarriageOrderService {
         return Global.NO;
     }
 
+    //冻结运费
+    public void freezePayable(AddLogisticOrderDTO orderDTO, List<LogisticData> logisticInfos,Map<Long, ContractCommonInfoResDto> longContractCommonInfoResDtoMap){
+        for (LogisticData x : logisticInfos) {
+            ContractCommonInfoResDto contractCommonInfoResDto = longContractCommonInfoResDtoMap.get(x.getContractId());
+            if (contractCommonInfoResDto == null) {
+                throw new BusinessException("合同不存在");
+            }
+            if(Objects.equals(contractCommonInfoResDto.getSettlement() ,1)){
+                // todo 普通结算模式
+
+            }else if((Objects.equals(contractCommonInfoResDto.getSettlement() ,2))){
+                //记账模式
+                WalletPayableDto payableUpdateDto = new WalletPayableDto();
+                payableUpdateDto.setConsignEntId(orderDTO.getConsignCompanyId());
+                payableUpdateDto.setCarriageEntId(x.getAcceptCompanyId());
+                payableUpdateDto.setOrderNo(String.valueOf(x.getLOrderId()));
+                payableUpdateDto.setOrderType(5);
+                payableUpdateDto.setTradeType(4);
+                payableUpdateDto.setTradeAmount(x.getPrice().multiply(x.getAmount()));
+                payableUpdateDto.setRemark("物流订单号:"+x.getLOrderId()+",下单冻结");
+                BaseResult<Object> freezeResult = paymentFeignService.updatePayable(payableUpdateDto);
+                if(freezeResult.getCode()!= HttpStatus.SUCCESS_CODE){
+                    log.error("物流订单号:{},下单冻结失败,异常信息为:{}",payableUpdateDto.getOrderNo(),freezeResult.getMessage());
+                    throw new BusinessException("物流订单号:"+payableUpdateDto.getOrderNo()+",订单下单冻结失败");
+                }
+            }
+        }
+    }
+
     /**
      * 获取装卸货地之间的导航距离
      * @param orderDTO
@@ -3619,9 +3657,10 @@ public class KwtAcceptCarriageOrderService {
         saveAddressList.add(unloadAddress);
     }
 
-    private static void setLogisticOrderInfo(AddLogisticOrderDTO orderDTO, LogisticData x, Long lOrderId, String lOrderNo, List<KwtLogisticsOrder> saveLogisticsOrderList,String distance) {
+    private static void setLogisticOrderInfo(AddLogisticOrderDTO orderDTO, LogisticData x, Long lOrderId, String lOrderNo, List<KwtLogisticsOrder> saveLogisticsOrderList,String distance, Map<Long, ContractCommonInfoResDto> longContractCommonInfoResDtoMap ) {
         KwtLogisticsOrder kwtLogisticsOrder = new KwtLogisticsOrder();
         kwtLogisticsOrder.setId(lOrderId);
+        x.setLOrderId(lOrderId);
         kwtLogisticsOrder.setEntId(orderDTO.getEntId());
         kwtLogisticsOrder.setType(String.valueOf(x.getType()));
         kwtLogisticsOrder.setTOrderId(orderDTO.getTradeOrderId());
@@ -3638,6 +3677,7 @@ public class KwtAcceptCarriageOrderService {
         kwtLogisticsOrder.setLossUnit(x.getLossUnit());
         kwtLogisticsOrder.setGoodsPrice(orderDTO.getGoodsPrice());
         kwtLogisticsOrder.setGoodsPriceUnit(orderDTO.getGoodsPriceUnit());
+        kwtLogisticsOrder.setSettlement(longContractCommonInfoResDtoMap.get(x.getContractId()).getSettlement());
         kwtLogisticsOrder.setStartTime(Objects.isNull(orderDTO.getStartTime()) ?
                 null : DateUtil.localDateToLocalDateTimeStart(orderDTO.getStartTime()));
         kwtLogisticsOrder.setEndTime(Objects.isNull(orderDTO.getEndTime()) ?

+ 63 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtLogisticsConsignmentService.java

@@ -27,6 +27,7 @@ import com.sckw.core.model.page.PageResult;
 import com.sckw.core.utils.*;
 import com.sckw.core.web.constant.HttpStatus;
 import com.sckw.core.web.context.LoginUserHolder;
+import com.sckw.core.web.response.BaseResult;
 import com.sckw.core.web.response.HttpResult;
 import com.sckw.core.web.response.result.PageDataResult;
 import com.sckw.excel.utils.DateUtil;
@@ -38,6 +39,8 @@ import com.sckw.mongo.model.SckwLogisticsOrder;
 import com.sckw.order.api.dubbo.RemoteTradeOrderAmountService;
 import com.sckw.order.api.dubbo.TradeOrderInfoService;
 import com.sckw.order.api.model.*;
+import com.sckw.payment.api.feign.PaymentFeignService;
+import com.sckw.payment.api.model.feign.WalletPayableDto;
 import com.sckw.product.api.dubbo.GoodsInfoService;
 import com.sckw.product.api.model.GoodsDetails;
 import com.sckw.product.api.model.KwpGoods;
@@ -142,6 +145,12 @@ public class KwtLogisticsConsignmentService {
     @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
     RemoteContractService contractService;
 
+    @Autowired
+    private KwtLogisticsOrderUnitRepository kwtLogisticsOrderUnitRepository;
+
+    @Autowired
+    private PaymentFeignService paymentFeignService;
+
     @Autowired
     DataPermissionFeignService dataPermissionFeignService;
 
@@ -3630,6 +3639,7 @@ public class KwtLogisticsConsignmentService {
             throw new BusinessException("未找到该物流订单信息");
         }
         List<KwtLogisticsOrder> logisticsOrders = Lists.newArrayList();
+        List<KwtLogisticsOrder> completedLogisticsOrders = Lists.newArrayList();
         Set<Long> tradeIds = Sets.newHashSet();
         logisticsOrder.forEach(x -> {
             KwtLogisticsOrder updateLogisticsOrder = new KwtLogisticsOrder();
@@ -3640,6 +3650,7 @@ public class KwtLogisticsConsignmentService {
             }
             if (Objects.equals(x.getStatus(), LogisticsOrderV1Enum.WAIT_DELIVERY.getCode())) {
                 updateLogisticsOrder.setStatus(LogisticsOrderV1Enum.COMPLETED.getCode());
+                completedLogisticsOrders.add(x);
                 logisticsOrders.add(updateLogisticsOrder);
                 tradeIds.add(x.getTOrderId());
                 return;
@@ -3650,6 +3661,7 @@ public class KwtLogisticsConsignmentService {
             List<KwtWaybillOrderSubtask> waybillOrderSubtasks = waybillOrderSubtaskRepository.queryByLogId(x.getId());
             if (org.apache.commons.collections4.CollectionUtils.isEmpty(waybillOrderSubtasks)) {
                 updateLogisticsOrder.setStatus(LogisticsOrderV1Enum.COMPLETED.getCode());
+                completedLogisticsOrders.add(x);
                 logisticsOrders.add(updateLogisticsOrder);
                 tradeIds.add(x.getTOrderId());
             }
@@ -3662,6 +3674,7 @@ public class KwtLogisticsConsignmentService {
                     logisticsOrders.add(updateLogisticsOrder);
                 } else {
                     updateLogisticsOrder.setStatus(LogisticsOrderV1Enum.COMPLETED.getCode());
+                    completedLogisticsOrders.add(x);
                     logisticsOrders.add(updateLogisticsOrder);
                     tradeIds.add(x.getTOrderId());
                 }
@@ -3674,11 +3687,61 @@ public class KwtLogisticsConsignmentService {
         }
         logisticsOrderRepository.updateBatchById(logisticsOrders);
 
+        calculateFreight(completedLogisticsOrders);
+
         //更新贸易订单数据
         // updateTradeOrder(tradeIds);
         return Boolean.TRUE;
     }
 
+    private void calculateFreight(List<KwtLogisticsOrder> completedLogisticsOrders){
+        for (KwtLogisticsOrder logisticsOrder : completedLogisticsOrders) {
+            //物流订单已完结,计算待付运费
+            if(Objects.equals(logisticsOrder.getSettlement(),1)){
+                //todo 普通结算
+
+            }else if(Objects.equals(logisticsOrder.getSettlement(),2)) {
+                //记账模式
+                //1解冻运费
+                List<KwtLogisticsOrderUnit> orderUnits = kwtLogisticsOrderUnitRepository.queryByLOrderId(logisticsOrder.getId());
+                Map<Integer, Long> map = orderUnits.stream().collect(Collectors.toMap(KwtLogisticsOrderUnit::getUnitType, KwtLogisticsOrderUnit::getEntId, (v1, v2) -> v1));
+                WalletPayableDto unFreezePayableDto = new WalletPayableDto();
+                unFreezePayableDto.setConsignEntId(map.get(1));
+                unFreezePayableDto.setCarriageEntId(map.get(2));
+                unFreezePayableDto.setOrderNo(String.valueOf(logisticsOrder.getId()));
+                unFreezePayableDto.setOrderType(5);
+                unFreezePayableDto.setTradeType(5);
+                unFreezePayableDto.setRemark("物流订单号:" + unFreezePayableDto.getOrderNo() + ",订单完结解冻");
+                BaseResult<Object> unFreezeResult = paymentFeignService.updatePayable(unFreezePayableDto);
+                if(unFreezeResult.getCode()!= HttpStatus.SUCCESS_CODE){
+                    log.error("物流订单号:{},订单完结解冻失败,异常信息为:{}",unFreezePayableDto.getOrderNo(),unFreezeResult.getMessage());
+                    throw new BusinessException("物流订单号:"+unFreezePayableDto.getOrderNo()+",订单完结解冻失败");
+                }
+                //2计算待付运费
+                WalletPayableDto consumePayableDto = new WalletPayableDto();
+                consumePayableDto.setConsignEntId(map.get(1));
+                consumePayableDto.setCarriageEntId(map.get(2));
+                consumePayableDto.setOrderNo(String.valueOf(logisticsOrder.getId()));
+                consumePayableDto.setOrderType(5);
+                consumePayableDto.setTradeType(6);
+                if (org.apache.commons.lang3.StringUtils.equals(logisticsOrder.getBillingMode(), DictEnum.CHARGING_TYPE_1.getValue())) {
+                    BigDecimal actualPrice = Objects.nonNull(logisticsOrder.getPrice()) && Objects.nonNull(logisticsOrder.getTotalLoadAmount()) ?
+                            logisticsOrder.getPrice().multiply(logisticsOrder.getTotalLoadAmount()) : BigDecimal.ZERO;
+                    consumePayableDto.setTradeAmount(actualPrice);
+                } else if (org.apache.commons.lang3.StringUtils.equals(logisticsOrder.getBillingMode(), DictEnum.CHARGING_TYPE_2.getValue())) {
+                    BigDecimal actualPrice = Objects.nonNull(logisticsOrder.getPrice()) && Objects.nonNull(logisticsOrder.getTotalUnloadAmount()) ?
+                            logisticsOrder.getPrice().multiply(logisticsOrder.getTotalUnloadAmount()) : BigDecimal.ZERO;
+                    consumePayableDto.setTradeAmount(actualPrice);
+                }
+                consumePayableDto.setRemark("物流订单号:" + consumePayableDto.getOrderNo() + ",订单完结消费");
+                BaseResult<Object> consumeResult = paymentFeignService.updatePayable(consumePayableDto);
+                if(consumeResult.getCode()!= HttpStatus.SUCCESS_CODE){
+                    log.error("物流订单号:{},订单完结消费失败,异常信息为:{}",unFreezePayableDto.getOrderNo(),consumeResult.getMessage());
+                    throw new BusinessException("物流订单号:"+unFreezePayableDto.getOrderNo()+",订单完结消费失败");
+                }
+            }
+        }
+    }
     private void updateTradeOrder(Set<Long> tradeIds) {
         if (org.apache.commons.collections4.CollectionUtils.isEmpty(tradeIds)) {
             return;

+ 53 - 1
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtWaybillOrderV1Service.java

@@ -32,6 +32,7 @@ import com.sckw.core.web.constant.CommonConstants;
 import com.sckw.core.web.constant.HttpStatus;
 import com.sckw.core.web.context.LoginUserHolder;
 import com.sckw.core.web.response.BaseIotResult;
+import com.sckw.core.web.response.BaseResult;
 import com.sckw.core.web.response.HttpResult;
 import com.sckw.core.web.response.result.PageDataResult;
 import com.sckw.excel.utils.DateUtil;
@@ -43,6 +44,8 @@ import com.sckw.order.api.dubbo.TradeOrderInfoService;
 import com.sckw.order.api.model.OrderDetailVo;
 import com.sckw.order.api.model.TradeOrderContractVo;
 import com.sckw.order.api.model.TradeOrderSettlePara;
+import com.sckw.payment.api.feign.PaymentFeignService;
+import com.sckw.payment.api.model.feign.WalletPayableDto;
 import com.sckw.product.api.dubbo.GoodsInfoService;
 import com.sckw.product.api.model.KwpGoods;
 import com.sckw.stream.enums.MessageEnum;
@@ -68,6 +71,7 @@ import com.sckw.transport.model.param.WaybillOrderReq;
 import com.sckw.transport.model.param.WaybillOrderResp;
 import com.sckw.transport.model.vo.*;
 import com.sckw.transport.repository.*;
+import io.seata.spring.annotation.GlobalTransactional;
 import jakarta.annotation.Resource;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.validation.Valid;
@@ -159,6 +163,8 @@ public class KwtWaybillOrderV1Service {
     private RemoteFleetService remoteFleetService;
     @DubboReference(version = "1.0.0", group = "design", check = false)
     private TradeOrderInfoService tradeOrderInfoService;
+    @Autowired
+    private PaymentFeignService paymentFeignService;
     @Value("${message.waybill.refuseSendCar.app}")
     private String refuseSendCarAppUrl;
     @Value("${message.waybill.refuseSendCar.pc}")
@@ -4606,7 +4612,8 @@ public class KwtWaybillOrderV1Service {
     }
 
 
-    @Transactional(rollbackFor = Exception.class)
+//    @Transactional(rollbackFor = Exception.class)
+    @GlobalTransactional(name = "default_tx_group")
     public Boolean reviewWaybillOrder(@Valid ReviewWaybillOrderReq req) {
         log.info("审核运单请求参数:{}", JSON.toJSONString(req));
         Long waybillId = Long.parseLong(req.getWaybillId());
@@ -4717,11 +4724,54 @@ public class KwtWaybillOrderV1Service {
             remoteFleetService.unbindTruck(billOrder.getEntId(), billOrder.getDriverId());
             return Boolean.TRUE;
         }
+        calculateFreight(kwtLogistics);
         noticeTraderOrder(status, subtask,kwtLogistics);
 
         return Boolean.FALSE;
     }
 
+    //计算运费
+    private void calculateFreight(KwtLogisticsOrder kwtLogistics){
+        if(LogisticsOrderV1Enum.COMPLETED.getCode().equals(kwtLogistics.getStatus())){
+            //物流订单已完结,计算待付运费
+            if(Objects.equals(kwtLogistics.getSettlement(),1)){
+                //todo 普通结算
+
+            }else if(Objects.equals(kwtLogistics.getSettlement(),2)) {
+                //记账模式
+                //1解冻运费
+                List<KwtLogisticsOrderUnit> orderUnits = kwtLogisticsOrderUnitRepository.queryByLOrderId(kwtLogistics.getId());
+                Map<Integer, Long> map = orderUnits.stream().collect(Collectors.toMap(KwtLogisticsOrderUnit::getUnitType, KwtLogisticsOrderUnit::getEntId, (v1, v2) -> v1));
+                WalletPayableDto unFreezePayableDto = new WalletPayableDto();
+                unFreezePayableDto.setConsignEntId(map.get(1));
+                unFreezePayableDto.setCarriageEntId(map.get(2));
+                unFreezePayableDto.setOrderNo(String.valueOf(kwtLogistics.getId()));
+                unFreezePayableDto.setOrderType(5);
+                unFreezePayableDto.setTradeType(5);
+                unFreezePayableDto.setRemark("物流订单号:" + unFreezePayableDto.getOrderNo() + ",订单完结解冻");
+                BaseResult<Object> unFreezeResult = paymentFeignService.updatePayable(unFreezePayableDto);
+                if(unFreezeResult.getCode()!= HttpStatus.SUCCESS_CODE){
+                    log.error("物流订单号:{},订单完结解冻失败,异常信息为:{}",unFreezePayableDto.getOrderNo(),unFreezeResult.getMessage());
+                    throw new BusinessException("物流订单号:"+unFreezePayableDto.getOrderNo()+",订单完结解冻失败");
+                }
+                //2计算待付运费
+                WalletPayableDto consumePayableDto = new WalletPayableDto();
+                consumePayableDto.setConsignEntId(map.get(1));
+                consumePayableDto.setCarriageEntId(map.get(2));
+                consumePayableDto.setOrderNo(String.valueOf(kwtLogistics.getId()));
+                consumePayableDto.setOrderType(5);
+                consumePayableDto.setTradeType(6);
+                consumePayableDto.setTradeAmount(kwtLogistics.getTotalUnloadAmount().multiply(kwtLogistics.getPrice()));
+                consumePayableDto.setRemark("物流订单号:" + consumePayableDto.getOrderNo() + ",订单完结消费");
+                BaseResult<Object> consumeResult = paymentFeignService.updatePayable(consumePayableDto);
+                if(consumeResult.getCode()!= HttpStatus.SUCCESS_CODE){
+                    log.error("物流订单号:{},订单完结消费失败,异常信息为:{}",unFreezePayableDto.getOrderNo(),consumeResult.getMessage());
+                    throw new BusinessException("物流订单号:"+unFreezePayableDto.getOrderNo()+",订单完结消费失败");
+                }
+            }
+        }
+    }
+
     private void updateLogisticOrder(KwtWaybillOrderSubtask subtask,KwtLogisticsOrder kwtLogistics) {
         if (Objects.nonNull(kwtLogistics) && Objects.equals(kwtLogistics.getStatus(), LogisticsOrderV1Enum.NEARING_COMPLETION.getCode())){
             List<KwtWaybillOrderSubtask> waybillOrderSubtasks = kwtWaybillOrderSubtaskRepository.queryByLogId(subtask.getLOrderId());
@@ -5176,6 +5226,7 @@ public class KwtWaybillOrderV1Service {
         kwtLogisticsOrder.setEntrustAmount(entrust);
        // kwtLogisticsOrder.setTotalLoadAmount(loadAmount.add(subLoadAmount));
         kwtLogisticsOrder.setTotalUnloadAmount(unloadAmount.add(subUnloadAmount));
+        kwtLogistics.setTotalUnloadAmount(kwtLogisticsOrder.getTotalUnloadAmount());
 
         //如果审核的状态是 完成,那么就要去查询物流订单状态是完结中,并且所有物流订单下的运单全部是完成或者取消如果是则更新状态为已完成
         if (Objects.equals(kwtLogistics.getStatus(), LogisticsOrderV1Enum.NEARING_COMPLETION.getCode()) && Objects.equals(status,CarWaybillV1Enum.COMPLETED.getCode())){
@@ -5185,6 +5236,7 @@ public class KwtWaybillOrderV1Service {
             if (b2){
                 log.info("物流订单状态修改为已完成,物流订单id:{}", kwtLogistics.getId());
                 kwtLogisticsOrder.setStatus(LogisticsOrderV1Enum.COMPLETED.getCode());
+                kwtLogistics.setStatus(kwtLogisticsOrder.getStatus());
             }
         }
         return kwtLogisticsOrder;

+ 69 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/task/LogisticsOrderCompletionTask.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.sckw.contract.api.RemoteContractService;
 import com.sckw.contract.api.feign.LogisticsScoreFeignService;
 import com.sckw.contract.api.model.dto.req.LogisticsScoreDetailFeignDto;
+import com.sckw.core.common.enums.enums.DictEnum;
 import com.sckw.core.common.enums.enums.ErrorCodeEnum;
 import com.sckw.core.exception.BusinessException;
 import com.sckw.core.exception.BusinessPlatfromException;
@@ -12,10 +13,14 @@ import com.sckw.core.model.enums.CarWaybillV1Enum;
 import com.sckw.core.model.enums.DispatchWayEnums;
 import com.sckw.core.model.enums.LogisticsOrderV1Enum;
 import com.sckw.core.utils.DateUtils;
+import com.sckw.core.web.constant.HttpStatus;
+import com.sckw.core.web.response.BaseResult;
 import com.sckw.fleet.api.RemoteFleetService;
 import com.sckw.fleet.api.model.dto.RUpdateDriverScoreDto;
 import com.sckw.fleet.api.model.vo.DriverConductRulesVO;
 import com.sckw.fleet.api.model.vo.TruckDispatchCoefficientVO;
+import com.sckw.payment.api.feign.PaymentFeignService;
+import com.sckw.payment.api.model.feign.WalletPayableDto;
 import com.sckw.transport.model.*;
 import com.sckw.transport.repository.*;
 import lombok.RequiredArgsConstructor;
@@ -63,6 +68,13 @@ public class LogisticsOrderCompletionTask {
     LogisticsScoreFeignService logisticsScoreFeignService;
 
 
+    @Autowired
+    private KwtLogisticsOrderUnitRepository kwtLogisticsOrderUnitRepository;
+
+    @Autowired
+    private PaymentFeignService paymentFeignService;
+
+
     /**
      * 定时任务:每5分钟执行一次
      * cron表达式:0 0/5 * * * ? 表示每5分钟执行一次
@@ -93,6 +105,8 @@ public class LogisticsOrderCompletionTask {
                     .map(KwtLogisticsOrder::getId)
                     .collect(Collectors.toList());
 
+            Map<Long, KwtLogisticsOrder> logisticOrderMap = nearingCompletionOrders.stream().collect(Collectors.toMap(KwtLogisticsOrder::getId, Function.identity()));
+
             // 根据物流订单ID查询相关运单子任务
             List<KwtWaybillOrderSubtask> subtasks = waybillOrderSubtaskRepository.queryByLogIds(logisticOrderIds);
 
@@ -102,6 +116,8 @@ public class LogisticsOrderCompletionTask {
 
             // 准备需要更新的物流订单列表
             List<KwtLogisticsOrder> updateLogisticOrders = new ArrayList<>();
+            //已完结需要计算运费的物流订单
+            List<KwtLogisticsOrder> completeLogisticOrders = new ArrayList<>();
 
             // 遍历每个物流订单及其关联的运单子任务
             logOrderSubtasksMap.forEach((logOrderId, subtaskList) -> {
@@ -127,6 +143,7 @@ public class LogisticsOrderCompletionTask {
                         // 定时任务更新,updateBy 可以设置为系统用户或0
                         updateOrder.setUpdateBy(0L);
                         updateLogisticOrders.add(updateOrder);
+                        completeLogisticOrders.add(logisticOrderMap.get(logOrderId));
 
                     } else {
                         // 存在未完成的运单,记录日志
@@ -148,6 +165,8 @@ public class LogisticsOrderCompletionTask {
 
             // 批量更新物流订单状态
             boolean updated = logisticsOrderRepository.updateBatchById(updateLogisticOrders);
+            //计算运费
+            calculateFreight(completeLogisticOrders);
             Set<Long> logOrderIds = updateLogisticOrders.stream().map(KwtLogisticsOrder::getId).collect(Collectors.toSet());
 
             // 记录更新结果日志
@@ -162,6 +181,56 @@ public class LogisticsOrderCompletionTask {
         }
     }
 
+    private void calculateFreight(List<KwtLogisticsOrder> completeLogisticOrders){
+        for (KwtLogisticsOrder logisticsOrder : completeLogisticOrders) {
+            //物流订单已完结,计算待付运费
+            if(Objects.equals(logisticsOrder.getSettlement(),1)){
+                //todo 普通结算
+
+            }else if(Objects.equals(logisticsOrder.getSettlement(),2)) {
+                //记账模式
+                //1解冻运费
+                List<KwtLogisticsOrderUnit> orderUnits = kwtLogisticsOrderUnitRepository.queryByLOrderId(logisticsOrder.getId());
+                Map<Integer, Long> map = orderUnits.stream().collect(Collectors.toMap(KwtLogisticsOrderUnit::getUnitType, KwtLogisticsOrderUnit::getEntId, (v1, v2) -> v1));
+                WalletPayableDto unFreezePayableDto = new WalletPayableDto();
+                unFreezePayableDto.setConsignEntId(map.get(1));
+                unFreezePayableDto.setCarriageEntId(map.get(2));
+                unFreezePayableDto.setOrderNo(String.valueOf(logisticsOrder.getId()));
+                unFreezePayableDto.setOrderType(5);
+                unFreezePayableDto.setTradeType(5);
+                unFreezePayableDto.setRemark("物流订单号:" + unFreezePayableDto.getOrderNo() + ",订单完结解冻");
+                BaseResult<Object> unFreezeResult = paymentFeignService.updatePayable(unFreezePayableDto);
+                if(unFreezeResult.getCode()!= HttpStatus.SUCCESS_CODE){
+                    log.error("物流订单号:{},订单完结解冻失败,异常信息为:{}",unFreezePayableDto.getOrderNo(),unFreezeResult.getMessage());
+                    throw new BusinessException("物流订单号:"+unFreezePayableDto.getOrderNo()+",订单完结解冻失败");
+                }
+                //2计算待付运费
+                WalletPayableDto consumePayableDto = new WalletPayableDto();
+                consumePayableDto.setConsignEntId(map.get(1));
+                consumePayableDto.setCarriageEntId(map.get(2));
+                consumePayableDto.setOrderNo(String.valueOf(logisticsOrder.getId()));
+                consumePayableDto.setOrderType(5);
+                consumePayableDto.setTradeType(6);
+                if (org.apache.commons.lang3.StringUtils.equals(logisticsOrder.getBillingMode(), DictEnum.CHARGING_TYPE_1.getValue())) {
+                    BigDecimal actualPrice = Objects.nonNull(logisticsOrder.getPrice()) && Objects.nonNull(logisticsOrder.getTotalLoadAmount()) ?
+                            logisticsOrder.getPrice().multiply(logisticsOrder.getTotalLoadAmount()) : BigDecimal.ZERO;
+                    consumePayableDto.setTradeAmount(actualPrice);
+                } else if (org.apache.commons.lang3.StringUtils.equals(logisticsOrder.getBillingMode(), DictEnum.CHARGING_TYPE_2.getValue())) {
+                    BigDecimal actualPrice = Objects.nonNull(logisticsOrder.getPrice()) && Objects.nonNull(logisticsOrder.getTotalUnloadAmount()) ?
+                            logisticsOrder.getPrice().multiply(logisticsOrder.getTotalUnloadAmount()) : BigDecimal.ZERO;
+                    consumePayableDto.setTradeAmount(actualPrice);
+                }
+                consumePayableDto.setRemark("物流订单号:" + consumePayableDto.getOrderNo() + ",订单完结消费");
+                BaseResult<Object> consumeResult = paymentFeignService.updatePayable(consumePayableDto);
+                if(consumeResult.getCode()!= HttpStatus.SUCCESS_CODE){
+                    log.error("物流订单号:{},订单完结消费失败,异常信息为:{}",unFreezePayableDto.getOrderNo(),consumeResult.getMessage());
+                    throw new BusinessException("物流订单号:"+unFreezePayableDto.getOrderNo()+",订单完结消费失败");
+                }
+            }
+        }
+
+    }
+
 
     /**
      * 定时任务:每2分钟执行一次

+ 10 - 0
sql/2026/04/2026_04_02_tangyishan_alter.sql

@@ -0,0 +1,10 @@
+ALTER TABLE `sckw_ng_order`.`kwo_trade_order`
+    ADD COLUMN `settlement` tinyint NOT NULL DEFAULT 1 COMMENT '结算方式 (1普通结算,2预付制结算)' AFTER `consignment_way`
+
+
+ALTER TABLE `sckw_ng_contract`.`kwc_contract_logistics`
+    ADD COLUMN `settlement` tinyint NOT NULL DEFAULT 1 COMMENT '结算方式 (1普通结算,2记账模式)' AFTER `dispatch_way`
+
+
+ALTER TABLE `sckw_ng_transport`.`kwt_logistics_order`
+    ADD COLUMN `settlement` tinyint NOT NULL COMMENT '结算方式 (1普通结算,2记账模式)' AFTER `dispatch_way`;