igl 2 долоо хоног өмнө
parent
commit
96d2026c7e
19 өөрчлөгдсөн 463 нэмэгдсэн , 15 устгасан
  1. 3 0
      vehicle-client/src/main/java/com/chelvc/cloud/vehicle/client/AssetClient.java
  2. 5 0
      vehicle-client/src/main/java/com/chelvc/cloud/vehicle/client/constant/TradeConstant.java
  3. 0 1
      vehicle-client/src/main/java/com/chelvc/cloud/vehicle/client/dto/WechatUnifiedOrder.java
  4. 9 0
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/controller/AssetController.java
  5. 1 1
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/controller/OmsOrderController.java
  6. 6 1
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/dao/MerchantRelationMapper.java
  7. 4 0
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/entity/OmsOrder.java
  8. 4 0
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/AssetService.java
  9. 6 0
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/MerchantRelationService.java
  10. 1 1
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/OmsOrderService.java
  11. 9 0
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/OrderHandleService.java
  12. 149 0
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/AssetServiceImpl.java
  13. 12 0
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/MerchantRelationServiceImpl.java
  14. 199 0
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/OderHandleServiceImpl.java
  15. 2 2
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/OmsOrderServiceImpl.java
  16. 1 2
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/OnlinePayServiceImpl.java
  17. 45 0
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/task/SyncBalanceTask.java
  18. 6 6
      vehicle-server/src/main/resources/application-test.yml
  19. 1 1
      vehicle-server/src/main/resources/application.yml

+ 3 - 0
vehicle-client/src/main/java/com/chelvc/cloud/vehicle/client/AssetClient.java

@@ -22,6 +22,9 @@ public interface AssetClient {
     @PostMapping(value = "/asset/transfer/notify")
     String transferNotify(@RequestBody SxyNotifyParam param);
 
+    @PostMapping(value = "/asset/split/order/notify")
+    String splitOrderNotify(@RequestBody SxyNotifyParam param);
+
     /**
      * 手动转账接口
      */

+ 5 - 0
vehicle-client/src/main/java/com/chelvc/cloud/vehicle/client/constant/TradeConstant.java

@@ -40,6 +40,11 @@ public interface TradeConstant {
      */
     static final String MERCHANT_NET_IN_NOTIFY_URL = "/maintain/merchant/apply/notify";
 
+    /**
+     * 分账回调地址
+     */
+    static final String SPLIT_ORDER_NOTIFY_URL = "/maintain/asset/split/order/notify";
+
     /**
      * 商户入网电子签重签回调地址
      */

+ 0 - 1
vehicle-client/src/main/java/com/chelvc/cloud/vehicle/client/dto/WechatUnifiedOrder.java

@@ -16,7 +16,6 @@ import lombok.experimental.SuperBuilder;
  * @date 2024/1/30
  */
 @Data
-@Deprecated
 @SuperBuilder
 @NoArgsConstructor
 @AllArgsConstructor

+ 9 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/controller/AssetController.java

@@ -50,6 +50,15 @@ public class AssetController {
         return this.assetService.transferNotify(param);
     }
 
+    /**
+     * 分账回调接口
+     *
+     */
+    @PostMapping("/asset/split/order/notify")
+    public String splitOrderNotify(@RequestBody SxyNotifyParam param) {
+        return this.assetService.splitOrderNotify(param);
+    }
+
     /**
      * 手动转账接口
      */

+ 1 - 1
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/controller/OmsOrderController.java

@@ -160,7 +160,7 @@ public class OmsOrderController {
      */
     @GetMapping("/omsOrder/getOrderDetail")
     public OmsOrderDetailDTO getOrderDetail(@RequestParam("orderSn") String orderSn,@RequestParam("merchantId") Long merchantId) {
-        return omsOrderService.getOraderDetail(orderSn,merchantId);
+        return omsOrderService.getOrderDetail(orderSn,merchantId);
     }
 
     /**

+ 6 - 1
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/dao/MerchantRelationMapper.java

@@ -3,9 +3,14 @@ package com.chelvc.cloud.vehicle.server.dao;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.chelvc.cloud.vehicle.server.entity.MerchantRelation;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
 
 @Mapper
 public interface MerchantRelationMapper extends BaseMapper<MerchantRelation> {
 
-
+    @Select("select * from merchant_relation limit #{pageNum}, #{pageSize}")
+    List<MerchantRelation> queryPage(@Param("pageNum")int pageNum, @Param("pageSize")int pageSize);
 }

+ 4 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/entity/OmsOrder.java

@@ -176,4 +176,8 @@ public class OmsOrder extends ModifyEntity<Long>
      * 收货地址ID
      */
     private Long userReceiveAddressId;
+    /**
+     * 分账订单号
+     */
+    private String requestId;
 }

+ 4 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/AssetService.java

@@ -64,4 +64,8 @@ public interface AssetService {
     int frozenAmount(BigDecimal amount, Long userId, Integer type);
 
     BigDecimal queryTotal(Long userId, Integer type);
+
+    void syncBalance();
+
+    String splitOrderNotify(SxyNotifyParam param);
 }

+ 6 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/MerchantRelationService.java

@@ -4,6 +4,8 @@ import com.chelvc.cloud.vehicle.server.entity.MerchantAuth;
 import com.chelvc.cloud.vehicle.server.entity.MerchantRelation;
 import com.chelvc.cloud.vehicle.server.entity.UserAuth;
 
+import java.util.List;
+
 public interface MerchantRelationService {
     MerchantRelation queryByUserIdAndType(Long userId, Integer type);
 
@@ -28,4 +30,8 @@ public interface MerchantRelationService {
      * @param frequency
      */
     void reSign(String requestId, String subMerchantId, int frequency);
+
+    long queryCount();
+
+    List<MerchantRelation> queryPage(int pageNum, int pageSize);
 }

+ 1 - 1
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/OmsOrderService.java

@@ -135,7 +135,7 @@ public interface OmsOrderService extends EnhanceService<OmsOrder>
     /**
      * 根据核销码获取订单详情
      */
-    OmsOrderDetailDTO getOraderDetail(String orderSn,Long merchantId);
+    OmsOrderDetailDTO getOrderDetail(String orderSn,Long merchantId);
 
     /**
      * 下单回调接口

+ 9 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/OrderHandleService.java

@@ -8,8 +8,17 @@ public interface OrderHandleService {
 
     void orderPay(Long orderId);
 
+    /**
+     * 订单核销处理(老方法)
+     * @param omsOrder
+     */
     void handleOrder(OmsOrder omsOrder);
 
+    /**
+     * 订单核销处理(分账)
+     * @param omsOrder
+     */
+    void splitOrder(OmsOrder omsOrder);
     /**
      * 支付成功回调处理
      * @param order

+ 149 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/AssetServiceImpl.java

@@ -1,5 +1,6 @@
 package com.chelvc.cloud.vehicle.server.service.impl;
 
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -10,8 +11,10 @@ import com.chelvc.cloud.vehicle.client.dto.*;
 import com.chelvc.cloud.vehicle.client.param.SxyNotifyParam;
 import com.chelvc.cloud.vehicle.client.param.WithdrawParam;
 import com.chelvc.cloud.vehicle.server.dao.AssetMapper;
+import com.chelvc.cloud.vehicle.server.dao.OmsOrderMapper;
 import com.chelvc.cloud.vehicle.server.entity.Asset;
 import com.chelvc.cloud.vehicle.server.entity.MerchantRelation;
+import com.chelvc.cloud.vehicle.server.entity.OmsOrder;
 import com.chelvc.cloud.vehicle.server.entity.OmsTransferWithdraw;
 import com.chelvc.cloud.vehicle.server.handle.TradeHandle;
 import com.chelvc.cloud.vehicle.server.service.*;
@@ -24,19 +27,31 @@ import com.upay.sdk.exception.RequestException;
 import com.upay.sdk.exception.ResponseException;
 import com.upay.sdk.exception.UnknownException;
 import com.upay.sdk.executer.ResultListenerAdpater;
+import com.upay.sdk.member.v_2.builder.BalanceBuilder;
+import com.upay.sdk.member.v_2.executer.MemberExecuter;
 import com.upay.sdk.transferaccount.builder.OrderBuilder;
 import com.upay.sdk.transferaccount.executer.TransferAccountOrderExecuter;
 import com.upay.sdk.wallet.builder.WithdrawBuilder;
 import com.upay.sdk.wallet.executer.WithdrawExecuter;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.DateFormatUtils;
+import org.apache.commons.lang3.time.DateUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
+
+import java.io.PrintWriter;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.stream.Collectors;
 
 @Slf4j
 @Service
@@ -46,6 +61,7 @@ public class AssetServiceImpl extends ServiceImpl<AssetMapper, Asset> implements
     private String NOTIFY_DOMAIN;
     private final BalanceDetailService balanceDetailService;
     private final OmsOrderService orderService;
+    private final OmsOrderMapper omsOrderMapper;
     private final MerchantService merchantService;
     private final MerchantRelationService merchantRelationService;
     private final OmsTransferWithdrawService transferWithdrawService;
@@ -386,6 +402,139 @@ public class AssetServiceImpl extends ServiceImpl<AssetMapper, Asset> implements
         return baseMapper.queryTotal(userId, type);
     }
 
+    @Override
+    public void syncBalance() {
+        int total = (int) merchantRelationService.queryCount();
+        int pageNum = 1;
+        int pageSize = 500;
+        int pages = 1;
+        if (total > pageSize) {
+            pages = total % pageSize != 0 ? (total / pageSize) + 1 : total / pageSize;
+        }
+        while (pageNum <= pages) {
+            List<MerchantRelation> result = merchantRelationService.queryPage(pageNum, pageSize);
+            syncBalance(result);
+            pageNum += 1;
+        }
+    }
+
+    @Override
+    public String splitOrderNotify(SxyNotifyParam param) {
+        String statusStr = "FAIL";
+        JSONObject responseData = TradeHandle.decrypt(param);
+        if(responseData == null){
+            return statusStr;
+        }
+        log.info("分账回调参数:{}", responseData);
+        String status = responseData.getString("splitStatus");
+        if("FINISHED".equals(status)){
+            log.info("分账完成");
+            String requestId = responseData.getString("requestId");
+            OmsOrder omsOrder = omsOrderMapper.selectOne(new LambdaQueryWrapper<OmsOrder>().eq(OmsOrder::getRequestId, requestId));
+            if(omsOrder != null){
+                Integer confirmStatus = omsOrder.getConfirmStatus();
+                if(confirmStatus == 1){
+                    return "SUCCESS";
+                }
+                omsOrder.setStatus(4);
+                omsOrder.setConfirmStatus(1);
+                omsOrder.setReceiveTime(new Date());
+                omsOrder.setUpdateTime(new Date());
+                omsOrder.setRequestId(requestId);
+                omsOrderMapper.updateById(omsOrder);
+            }
+        }
+        return statusStr;
+    }
+
+    public void syncBalance(List<MerchantRelation> list){
+        if(!list.isEmpty()){
+            list.forEach(e -> {
+                BigDecimal balance = queryBalance(e.getSxyMerchantId());
+                Asset asset = baseMapper.selectOne(new LambdaQueryWrapper<Asset>().eq(Asset::getUserId, e.getUserId()).eq(Asset::getType, e.getType()));
+                if(asset == null){
+                    asset = new Asset();
+                    asset.setUserId(e.getUserId());
+                    asset.setType(2);
+                    asset.setTotal(balance);
+                    asset.setUpdateTime(LocalDateTime.now());
+                    asset.setFrozen(BigDecimal.ZERO);
+                    baseMapper.insert(asset);
+                    return;
+                }
+                BigDecimal frozen = asset.getFrozen();
+                if(frozen.compareTo(balance) > 0){
+                    return;
+                }
+                asset.setTotal(balance.subtract(asset.getFrozen()));
+                asset.setUpdateTime(LocalDateTime.now());
+                baseMapper.updateById(asset);
+            });
+        }
+    }
+
+    public BigDecimal queryBalance(String sxyMerchantId){
+        final BigDecimal[] amount = {BigDecimal.ZERO};
+        //订单编号
+        String requestId = UUID.randomUUID().toString().replaceAll("-", "");
+        //查询币种
+        String currency = "CNY";
+        //账户类型
+        String accountType = "settlementAccount";
+        //服务商id
+        String partnerId = TradeConstant.PARTNER_ID;
+        //时间戳
+        //String dateTime = req.getParameter("dateTime");
+        //为方便测试,时间戳自动取系统时间,-2秒,避免本地时间快于服务器时间
+        String dateTime = DateFormatUtils.format(DateUtils.addSeconds(new Date(), -2), "yyyy-MM-dd HH:mm:ss");
+
+        BalanceBuilder builder = new BalanceBuilder(sxyMerchantId);
+        builder.setCurrency(currency)
+                .setRequestId(requestId)
+                .setAccountType(accountType)
+                .setDateTime(dateTime)
+                .setPartnerId(partnerId);
+        try {
+            MemberExecuter executer = new MemberExecuter();
+            executer.bothBalanceQuery(builder, new ResultListenerAdpater() {
+                @Override
+                public void success(JSONObject jsonObject) {
+                    log.info("处理成功: {}", jsonObject.toJSONString());
+                    JSONArray accountList = jsonObject.getJSONArray("accountList");
+                    JSONObject firstAccount = accountList.getJSONObject(0);
+                    long availableBalance = firstAccount.getIntValue("availableBalance");
+                    amount[0] = new BigDecimal(availableBalance).divide(new BigDecimal("100"), 2, RoundingMode.UP);
+                }
+                @Override
+                public void failure(JSONObject jsonObject) {
+                    log.error("处理失败!<br/>");
+                    String result = jsonObject.toJSONString();
+                    log.error(result);
+                }
+
+                @Override
+                public void pending(JSONObject jsonObject) {
+                    log.error("待处理!<br/>");
+                    String result = jsonObject.toJSONString();
+                    log.error(result);
+                }
+            });
+        } catch (ResponseException e) {
+            log.error("响应异常</br>");
+            log.error(e.toString());
+        } catch (HmacVerifyException e) {
+            log.error("签名验证异常</br>");
+            log.error(e.toString());
+        } catch (RequestException e) {
+            log.error("请求异常</br>");
+            log.error(e.toString());
+        } catch (UnknownException e) {
+            log.error("未知异常</br>");
+            log.error(e.toString());
+        }
+        return amount[0];
+    }
+
     @Override
     public String transferNotify(SxyNotifyParam param) {
         String statusStr = "FAIL";

+ 12 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/MerchantRelationServiceImpl.java

@@ -25,7 +25,9 @@ import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 
 import java.text.SimpleDateFormat;
+import java.util.Collections;
 import java.util.Date;
+import java.util.List;
 import java.util.UUID;
 
 @Service
@@ -285,4 +287,14 @@ public class MerchantRelationServiceImpl extends ServiceImpl<MerchantRelationMap
                 TradeConstant.PARTNER_ID, null);
         log.info("子商户【{}】电子签重签返回信息:{}", subMerchantId, json);
     }
+
+    @Override
+    public long queryCount() {
+        return baseMapper.selectCount(new LambdaQueryWrapper<MerchantRelation>());
+    }
+
+    @Override
+    public List<MerchantRelation> queryPage(int pageNum, int pageSize) {
+        return baseMapper.queryPage(pageNum, pageSize);
+    }
 }

+ 199 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/OderHandleServiceImpl.java

@@ -1,15 +1,28 @@
 package com.chelvc.cloud.vehicle.server.service.impl;
 
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.chelvc.cloud.vehicle.client.constant.PlatformConstant;
+import com.chelvc.cloud.vehicle.client.constant.TradeConstant;
 import com.chelvc.cloud.vehicle.client.dto.UserCouponDTO;
 import com.chelvc.cloud.vehicle.server.dao.OmsOrderMapper;
 import com.chelvc.cloud.vehicle.server.entity.MerchantRelation;
 import com.chelvc.cloud.vehicle.server.entity.OmsOrder;
 import com.chelvc.cloud.vehicle.server.service.*;
 import com.chelvc.framework.common.exception.ResourceUnavailableException;
+import com.upay.sdk.entity.SplitDetail;
+import com.upay.sdk.exception.HmacVerifyException;
+import com.upay.sdk.exception.RequestException;
+import com.upay.sdk.exception.ResponseException;
+import com.upay.sdk.exception.UnknownException;
+import com.upay.sdk.executer.ResultListenerAdpater;
+import com.upay.sdk.onlinepay.builder.SplitOrderBuilder;
+import com.upay.sdk.onlinepay.executer.OnlinePayOrderExecuter;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -17,6 +30,7 @@ import org.springframework.stereotype.Service;
 import java.io.BufferedInputStream;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.PrintWriter;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.nio.charset.StandardCharsets;
@@ -28,7 +42,11 @@ import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.Date;
 import java.util.Objects;
+import java.util.UUID;
 
+import static com.chelvc.cloud.vehicle.client.constant.TradeConstant.NOTIFY_DOMAIN;
+
+@Slf4j
 @Service
 @RequiredArgsConstructor(onConstructor = @__(@Autowired))
 public class OderHandleServiceImpl implements OrderHandleService {
@@ -227,6 +245,187 @@ public class OderHandleServiceImpl implements OrderHandleService {
         }*/
     }
 
+    @Override
+    public void splitOrder(OmsOrder omsOrder) {
+        //分账订单号
+        String requestId = UUID.randomUUID().toString().replaceAll("-", "");
+        omsOrder.setStatus(4);
+        omsOrder.setConfirmStatus(1);
+        omsOrder.setReceiveTime(new Date());
+        omsOrder.setUpdateTime(new Date());
+        omsOrder.setRequestId(requestId);
+        int i = omsOrderMapper.updateById(omsOrder);
+        if (i != 1) {
+            throw new ResourceUnavailableException("处理失败");
+        }
+        //分佣逻辑=====================================
+        //实际支付金额
+        BigDecimal payAmount = omsOrder.getPayAmount();
+        Long userId = omsOrder.getUserId();
+        Long merchantId = omsOrder.getMerchantId();
+
+        BigDecimal userAmount = BigDecimal.ZERO;
+        BigDecimal merchantAmount = BigDecimal.ZERO;
+        BigDecimal feeAmount = omsOrder.getFeeAmount();
+        //计算优惠券
+        Long couponId = omsOrder.getCouponId();
+        if(couponId != null){
+            UserCouponDTO userCoupon = userCouponService.getUserCoupon(couponId);
+            if(userCoupon != null){
+                Long couponMerchantId = userCoupon.getMerchantId();
+                if(couponMerchantId == 0L){
+                    //平台补贴给商家
+                    BigDecimal couponAmount = omsOrder.getCouponAmount();
+                    //给商家转账
+                    assetService.transfer(0L, merchantId, 2, couponAmount, "平台优惠券补贴");
+                    //更新平台资产
+                    BigDecimal platformTotal = assetService.updateAsset(1, couponAmount, 0L, 0, 1);
+                    //记录平台余额明细
+                    balanceDetailService.recordFlow(omsOrder.getId(), 0, 0L, couponAmount, BigDecimal.ZERO,
+                            couponAmount, platformTotal, 1, 9, merchantId);
+                    BigDecimal surplusAmount = assetService.updateAsset(0, couponAmount, merchantId, 2, 1);
+                }
+            }
+        }
+        String sxyMerchantId = TradeConstant.PARTNER_ID;
+        //原订单流水号(serialNumber)是交易流水号而不是银行流水号
+        Long orderId = omsOrder.getId();
+        //此处为退款金额
+        String totalSplitAmount = String.valueOf(payAmount.multiply(new BigDecimal("100")));
+        //服务商id
+        String partnerId = TradeConstant.PARTNER_ID;
+        //通知地址
+        String notifyUrl = NOTIFY_DOMAIN + TradeConstant.SPLIT_ORDER_NOTIFY_URL;
+        SplitOrderBuilder builder = new SplitOrderBuilder(sxyMerchantId);
+        builder.setOrderId(String.valueOf(orderId))
+                .setRequestId(requestId)
+                .setTotalSplitAmount(totalSplitAmount)
+                .setNotifyUrl(notifyUrl);
+        builder.setPartnerId(partnerId);
+
+        MerchantRelation merchantRelation = merchantRelationService.queryByUserIdAndType(merchantId, 2);
+        //应该分账金额
+        BigDecimal splitAmount = payAmount.subtract(feeAmount);
+        //平台抽佣
+        int platformRatio = platformProfitRatioService.queryRatio(merchantId);
+        //平台抽佣金额----向上取整保留2位小数
+        BigDecimal platformAmount = new BigDecimal(platformRatio).divide(new BigDecimal("100"), 2, RoundingMode.UP)
+                .multiply(splitAmount).setScale(2, RoundingMode.UP);
+
+        //售卖商家应得金额
+        BigDecimal goodsMerchantAmount = splitAmount.subtract(platformAmount);
+
+        //售卖商家分账
+        SplitDetail splitDetail = getSplitStr(merchantRelation.getSxyMerchantId(), goodsMerchantAmount);
+        builder.addSplitDetails(splitDetail);
+
+        //用户抽佣----查看消费用户上级
+        boolean flag = false;
+        Long inviteUserId = userInviteService.queryUserByTarget(userId, 1);
+        if (inviteUserId != null) {
+            //用户分佣
+            int userRatio = userProfitRatioService.queryRatio(inviteUserId, 1);
+            if (userRatio > 0) {
+                userAmount = new BigDecimal(userRatio).divide(new BigDecimal("100"), 2, RoundingMode.UP)
+                        .multiply(platformAmount).setScale(2, RoundingMode.UP);
+                MerchantRelation relation = merchantRelationService.queryByUserIdAndType(inviteUserId, 1);
+                if(relation != null && StringUtils.isNotBlank(relation.getSxyMerchantId()) && userAmount.compareTo(BigDecimal.ZERO) > 0){
+                    flag = true;
+                    //邀请用户分账
+                    SplitDetail splitUserDetail = getSplitStr(relation.getSxyMerchantId(), userAmount);
+                    builder.addSplitDetails(splitUserDetail);
+                }
+            }
+        }
+        //商户抽佣----查看消费用户上级
+        Long inviteMerchantId = userInviteService.queryUserByTarget(merchantId, 2);
+        if (inviteMerchantId != null) {
+            //商户分佣
+            int merchantRatio = userProfitRatioService.queryRatio(inviteMerchantId, 2);
+            MerchantRelation inviteMerchantRelation = merchantRelationService.queryByUserIdAndType(inviteMerchantId, 2);
+            if (merchantRatio > 0 && StrUtil.isNotBlank(inviteMerchantRelation.getSxyMerchantId())) {
+                merchantAmount = new BigDecimal(merchantRatio).divide(new BigDecimal("100"), 2, RoundingMode.UP)
+                        .multiply(platformAmount).setScale(2, RoundingMode.UP);
+                if(merchantAmount.compareTo(BigDecimal.ZERO) > 0){
+                    SplitDetail splitStr = getSplitStr(inviteMerchantRelation.getSxyMerchantId(), merchantAmount);
+                    builder.addSplitDetails(splitStr);
+                }
+            }
+        }
+        BigDecimal platformRealAmount = platformAmount.subtract(merchantAmount);
+        if(flag){
+            platformRealAmount = platformRealAmount.subtract(userAmount);
+        }
+        platformRealAmount = platformRealAmount.add(feeAmount);
+        if(platformRealAmount.compareTo(BigDecimal.ZERO) > 0){
+            SplitDetail splitStr = getSplitStr(TradeConstant.PARTNER_ID, platformRealAmount);
+            builder.addSplitDetails(splitStr);
+        }
+        try {
+            OnlinePayOrderExecuter executer = new OnlinePayOrderExecuter();
+            BigDecimal finalPlatformRealAmount = platformRealAmount;
+            BigDecimal finalMerchantAmount = merchantAmount;
+            boolean finalFlag = flag;
+            executer.bothSplitOrder(builder, new ResultListenerAdpater() {
+                /**
+                 * 提交成功
+                 */
+                @Override
+                public void success(JSONObject jsonObject) {
+                    log.info("分账成功:{}", jsonObject);
+                    assetService.updatePlatformAsset(finalPlatformRealAmount, payAmount);
+                    assetService.updateAsset(0, goodsMerchantAmount, merchantId, 2, 1);
+                    if(finalMerchantAmount.compareTo(BigDecimal.ZERO) > 0){
+                        assetService.updateAsset(0, finalMerchantAmount, inviteMerchantId, 2, 1);
+                    }
+                    if(finalFlag){
+                        assetService.updateAsset(0, finalMerchantAmount, inviteUserId, 1, 1);
+                    }
+                }
+            });
+        } catch (ResponseException e) {
+            log.error("响应异常</br>");
+            log.error(e.toString());
+        } catch (HmacVerifyException e) {
+            log.error("签名验证异常</br>");
+            log.error(e.toString());
+        } catch (RequestException e) {
+            log.error("请求异常</br>");
+            log.error(e.toString());
+        } catch (UnknownException e) {
+            log.error("未知异常</br>");
+            log.error(e.toString());
+        }
+
+        //邀请用户---分得佣金
+        if (userAmount.compareTo(BigDecimal.ZERO) > 0) {
+            BigDecimal deduct = BigDecimal.ZERO;  //扣税
+            BigDecimal realityAmount = userAmount.subtract(deduct);
+            if(!flag){
+                //更新用户资产
+                BigDecimal userTotal = assetService.updateAsset(0, realityAmount, inviteUserId, 1, 1);
+                //邀请用户余额明细
+                balanceDetailService.recordFlow(orderId, 1, inviteUserId, userAmount, deduct,
+                        realityAmount, userTotal, 0, 1, userId);
+                //用户资产记录到平台名下
+                BigDecimal platformTotal = assetService.updateAsset(0, realityAmount, 0L, 0, 1);
+                //用户佣金记录到平台余额名下
+                balanceDetailService.recordFlow(orderId, 0, 0L, userAmount, deduct,
+                        realityAmount, platformTotal, 0, 1, userId);
+            }
+        }
+    }
+
+    public SplitDetail getSplitStr(String merchantId, BigDecimal amount){
+        SplitDetail splitDetail = new SplitDetail();
+        splitDetail.setSubSplitRequestId(UUID.randomUUID().toString().replaceAll("-", ""));
+        splitDetail.setSplitAccId(merchantId);
+        splitDetail.setSplitAccType("MERCHANT_ACC");
+        splitDetail.setSplitAmount(amount.multiply(new BigDecimal("100")).longValue());
+        splitDetail.setRemark("收益");
+        return splitDetail;
+    }
+
     @Override
     public void paySuccess(OmsOrder order) {
         omsOrderMapper.updateById(order);

+ 2 - 2
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/OmsOrderServiceImpl.java

@@ -1060,7 +1060,7 @@ public class OmsOrderServiceImpl extends ServiceImpl<OmsOrderMapper, OmsOrder> i
         AssertUtils.available(status == 1, "该订单不可用");
         DatabaseContextHolder.transactional((Executor) () -> {
             //处理分佣逻辑
-            orderHandleService.handleOrder(omsOrder);
+            orderHandleService.splitOrder(omsOrder);
             this.reservationService.updateStatusByOrderId(orderId, ReserveStatus.COMPLETED);
         });
     }
@@ -1096,7 +1096,7 @@ public class OmsOrderServiceImpl extends ServiceImpl<OmsOrderMapper, OmsOrder> i
     }
 
     @Override
-    public OmsOrderDetailDTO getOraderDetail(String orderSn,Long merchantId) {
+    public OmsOrderDetailDTO getOrderDetail(String orderSn,Long merchantId) {
         OmsOrder omsOrder = this.lambdaQuery()
                 .eq(OmsOrder::getOrderSn,orderSn)
                 .eq(OmsOrder::getMerchantId,merchantId)

+ 1 - 2
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/OnlinePayServiceImpl.java

@@ -53,7 +53,6 @@ public class OnlinePayServiceImpl  implements OnlinePayService {
     private final UserClient userService;
     private final OmsOrderRefundService omsOrderRefundService;
     private final AssetService assetService;
-    private final MerchantRelationService merchantRelationService;
 
     @Override
     public WechatUnifiedOrder order(OmsOrder omsOrder, List<OmsOrderItem> orderItemList, OmsOrderModifyParam orderParam){
@@ -83,7 +82,7 @@ public class OnlinePayServiceImpl  implements OnlinePayService {
         //builder.setReportTerminalNo("");
         //builder.setPartnerId(TradeConstant.PARTNER_ID);
         builder.setProjectId(String.valueOf(omsOrder.getMerchantId()));
-        //builder.setSplitMark("");  //不传默认不分账
+        builder.setSplitMark("DO_SPLIT");  //不传默认不分账
 
 
         //productDetails(商品信息)

+ 45 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/task/SyncBalanceTask.java

@@ -0,0 +1,45 @@
+package com.chelvc.cloud.vehicle.server.task;
+
+import com.alibaba.fastjson.JSONObject;
+import com.chelvc.cloud.vehicle.client.constant.TradeConstant;
+import com.chelvc.cloud.vehicle.server.dao.MerchantRelationMapper;
+import com.chelvc.cloud.vehicle.server.service.AssetService;
+import com.upay.sdk.exception.HmacVerifyException;
+import com.upay.sdk.exception.RequestException;
+import com.upay.sdk.exception.ResponseException;
+import com.upay.sdk.exception.UnknownException;
+import com.upay.sdk.executer.ResultListenerAdpater;
+import com.upay.sdk.member.v_2.builder.BalanceBuilder;
+import com.upay.sdk.member.v_2.executer.MemberExecuter;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.DateFormatUtils;
+import org.apache.commons.lang3.time.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.io.PrintWriter;
+import java.util.Date;
+
+/**
+ * @desc : 余额同步查询
+ * @author: igl
+ * @since : 2025/8/19
+ **/
+@Slf4j
+@Component
+@EnableScheduling
+public class SyncBalanceTask {
+
+    @Autowired
+    AssetService assetService;
+
+    @Scheduled(cron = "0 0 0/6 * * ?")
+    public void syncBalance() {
+        log.info("同步余额开始: {}", new Date());
+        assetService.syncBalance();
+        log.info("同步余额结束: {}", new Date());
+    }
+}

+ 6 - 6
vehicle-server/src/main/resources/application-test.yml

@@ -2,19 +2,19 @@ spring:
   cloud:
     nacos:
       discovery:
-        server-addr: 127.0.0.1:6848
+        server-addr: 127.0.0.1:8848
   datasource:
-    url: jdbc:mysql://127.0.0.1:6180/vehicle?characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true&useAffectedRows=true
-    username: vehicle
-    password: Chelvc@vehicle!2023#
+    url: jdbc:mysql://127.0.0.1:3306/vehicle?characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true&useAffectedRows=true
+    username: root
+    password: igl611
   redis:
     host: 127.0.0.1
-    port: 7031
+    port: 6379
     password: Chelvc@2023
 
 nacos:
   config:
-    server-addr: 127.0.0.1:6848
+    server-addr: 127.0.0.1:8848
 
 location:
   clients:

+ 1 - 1
vehicle-server/src/main/resources/application.yml

@@ -16,7 +16,7 @@ spring:
   main:
     allow-bean-definition-overriding: true
   profiles:
-    active: local
+    active: test
   application:
     name: vehicle
   jackson: