chenxiaofei 2 месяцев назад
Родитель
Сommit
cde7a788e9

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

@@ -0,0 +1,39 @@
+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);
+
+}

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

@@ -0,0 +1,32 @@
+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;
+}

+ 11 - 4
sckw-modules/sckw-order/src/main/java/com/sckw/order/model/vo/req/CancelTradeOrderParam.java

@@ -7,18 +7,25 @@ import lombok.Setter;
 import lombok.ToString;
 import org.hibernate.validator.constraints.Length;
 
+import java.math.BigDecimal;
+
 @Getter
 @Setter
 @ToString
 @Schema(description = "买家撤销贸易订单参数")
 public class CancelTradeOrderParam {
 
-    @NotNull(message = "订单id不能为空")
-    @Schema(description = "贸易订单id")
-    private Long id;
-
     @Length(max = 200, message = "撤销原因最多200字")
     @Schema(description = "撤销原因")
     private String remark;
 
+    @Schema(description = "贸易合同")
+    private Long tradeContractId;
+
+    @Schema(description = "商品id")
+    private Long goodsId;
+
+    //冻结金额
+    @Schema(description = "冻结金额")
+    private BigDecimal freezeAmount;
 }

+ 80 - 11
sckw-modules/sckw-order/src/main/java/com/sckw/order/serivce/KwoTradeOrderService.java

@@ -56,9 +56,11 @@ 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.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.product.api.dubbo.GoodsInfoService;
 import com.sckw.product.api.model.AddressInfoDetail;
@@ -134,6 +136,8 @@ public class KwoTradeOrderService {
     @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
     protected RemoteFleetService remoteFleetService;
 
+    private final OfflineWalletFeignService offlineWalletFeignService;
+
     private final KwoTradeOrderMapper kwoTradeOrderMapper;
     private final StreamBridge streamBridge;
     private final KwoTradeOrderAddressService kwoTradeOrderAddressService;
@@ -2014,8 +2018,7 @@ public class KwoTradeOrderService {
 
         // ====== 下单前校验 start ======
         // 1. 验证线下钱包预付余额是否足够,不足则提示"线下钱包预付余额不足"
-        // TODO: 后续对接外部系统,验证线下钱包预付余额
-        // validateOfflineWalletBalance(buyEntId, order.getPrice());
+        checkWallet(order);
 
         // 2. 验证商品是否开启库存(amount不为null代表已开启库存,null代表无限库存无需验证)
         if (goodsById.getAmount() != null && goodsById.getAmount().compareTo(tradeOrderParam.getAmount()) < 0) {
@@ -2024,10 +2027,6 @@ public class KwoTradeOrderService {
             }
         }
 
-        // 3. 线下钱包扣减预付余额、增加冻结金额
-        // TODO: 后续对接外部系统,执行线下钱包扣减预付余额、增加冻结金额
-        // deductOfflineWalletAndFreeze(buyEntId, order.getPrice());
-
         // 4. 记录钱包金额账数据,类型为冻结,备注为"贸易订单号:xxx 下单冻结"
         // TODO: 后续对接外部系统,记录钱包流水
         // recordWalletTransaction(buyEntId, order.getPrice(), "冻结", "贸易订单号:" + order.getTOrderNo() + " 下单冻结");
@@ -2158,7 +2157,7 @@ public class KwoTradeOrderService {
             }
         }
         List<TradeContractUnitDto> unitList = tradeContractResDto.getUnitList();
-
+        WalletFreezeDto freezeDto = new WalletFreezeDto();
         List<KwoTradeOrderUnit> list = new ArrayList<>();
         unitList.forEach(e -> {
             KwoTradeOrderUnit unit = BeanUtil.copyProperties(e, KwoTradeOrderUnit.class);
@@ -2167,9 +2166,11 @@ public class KwoTradeOrderService {
             unit.setUnitType(StrUtil.equals(e.getUnitType(), "1") ? "2" : "1");//贸易合同和订单的单位类型相反
             if (StrUtil.equals(unit.getUnitType(), "1")) {
                 walletFreeze.setBuyEntId(unit.getEntId());
+                freezeDto.setProEntId(unit.getEntId());
             }
             if (StrUtil.equals(unit.getUnitType(), "2")) {
                 walletFreeze.setSaleEntId(unit.getEntId());
+                freezeDto.setSupEntId(unit.getEntId());
             }
             list.add(unit);
         });
@@ -2179,7 +2180,46 @@ public class KwoTradeOrderService {
         if (booleanBaseResult.getCode() != 60200) {
             throw new BusinessException(booleanBaseResult.getMessage());
         }
+        // 3. 线下钱包扣减预付余额、增加冻结金额
+        walletFreeze(tradeOrderParam, order,freezeDto);
+    }
+
+    private void walletFreeze(TradeOrderParam tradeOrderParam, KwoTradeOrder order,WalletFreezeDto freezeDto) {
+
+        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) {
+        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("线下钱包预付余额不足");
+        }
     }
 
     /**
@@ -2188,7 +2228,7 @@ public class KwoTradeOrderService {
     public void cancelTradeOrder(CancelTradeOrderParam param) {
         KwoTradeOrder order = kwoTradeOrderMapper.selectOne(
                 new LambdaQueryWrapper<KwoTradeOrder>()
-                        .eq(KwoTradeOrder::getId, param.getId())
+                        .eq(KwoTradeOrder::getId, param.getTradeContractId())
                         .eq(KwoTradeOrder::getDelFlag, 0)
         );
         if (Objects.isNull(order)) {
@@ -2197,10 +2237,39 @@ public class KwoTradeOrderService {
         if (!Objects.equals(order.getStatus(), TradeOrderStatusEnum.AUDIT.getCode())) {
             throw new BusinessException("当前订单状态不允许撤销");
         }
-
+        TradeContractResDto tradeContractResDto = remoteContractService.queryTradeContract(param.getTradeContractId(), param.getGoodsId());
         // 1. 线下钱包加回预付余额、减冻结金额
-        // TODO: 后续对接外部系统,执行线下钱包加回预付余额、减冻结金额
-        // refundOfflineWalletPrepaid(buyEntId, order.getPrice());
+        List<TradeContractUnitDto> unitList = tradeContractResDto.getUnitList();
+        WalletFreezeDto freezeDto = new WalletFreezeDto();
+        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")) {
+                freezeDto.setProEntId(unit.getEntId());
+            }
+            if (StrUtil.equals(unit.getUnitType(), "2")) {
+                freezeDto.setSupEntId(unit.getEntId());
+            }
+        });
+         freezeDto.setFreezeAmount(param.getFreezeAmount());
+         freezeDto.setOrderNo(order.getTOrderNo());
+
+        BaseResult<Boolean> balanceResult;
+        try {
+            balanceResult = offlineWalletFeignService.unfreezeBalance(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("线下钱包扣减预付余额、增加冻结金额失败");
+        }
 
         // 2. 记录钱包金额账数据,类型为解冻,备注为"贸易订单号:xxx 撤销订单"
         // TODO: 后续对接外部系统,记录钱包流水