瀏覽代碼

分账回归

liujc 1 年之前
父節點
當前提交
777ce66740

+ 61 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/DivBackRecord.java

@@ -0,0 +1,61 @@
+package com.yonge.cooleshow.biz.dal.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import lombok.Data;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 分账归还记录
+ * 2023-10-18 10:59:05
+ */
+@Data
+@ApiModel(" DivBackRecord-分账归还记录")
+@TableName("div_back_record")
+public class DivBackRecord implements Serializable {
+
+    @ApiModelProperty("主键") 
+	    @TableId(value = "id_",type = IdType.AUTO)
+	    private Long id;
+
+    @ApiModelProperty("分账记录ID") 
+	@TableField(value = "payment_div_member_record_id_")
+    private Long paymentDivMemberRecordId;
+
+    @ApiModelProperty("分账归还订单号") 
+	@TableField(value = "divide_back_order_no_")
+    private String divideBackOrderNo;
+
+    @ApiModelProperty("分账归还三方号") 
+	@TableField(value = "divide_back_trans_no_")
+    private String divideBackTransNo;
+
+    @ApiModelProperty("分账归还状态") 
+	@TableField(value = "status_")
+    private String status;
+
+    @ApiModelProperty("失败原因") 
+	@TableField(value = "reason_")
+    private String reason;
+
+    @ApiModelProperty("尝试次数")
+    @TableField(value = "times_")
+    private Integer times;
+
+    @ApiModelProperty("创建时间") 
+	@TableField(value = "create_time_")
+    private Date createTime;
+
+    @ApiModelProperty("更新时间") 
+	@TableField(value = "update_time_")
+    private Date updateTime;
+
+}

+ 27 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/DivBackRecordMapper.java

@@ -0,0 +1,27 @@
+package com.yonge.cooleshow.biz.dal.mapper;
+
+import java.util.List;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+import com.yonge.cooleshow.biz.dal.entity.DivBackRecord;
+import com.yonge.cooleshow.biz.dal.wrapper.DivBackRecordWrapper;
+
+/**
+ * 分账归还记录
+ * 2023-10-18 10:59:05
+ */
+@Repository
+public interface DivBackRecordMapper extends BaseMapper<DivBackRecord> {
+
+	/**
+	 * 分页查询
+	 * @param page IPage<DivBackRecordWrapper.DivBackRecord>
+	 * @param param DivBackRecordWrapper.DivBackRecordQuery
+	 * @return List<DivBackRecordWrapper.DivBackRecord>
+	 */
+	List<DivBackRecord> selectPage(@Param("page") IPage<DivBackRecord> page, @Param("param") DivBackRecordWrapper.DivBackRecordQuery param);
+	
+}

+ 43 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/DivBackRecordService.java

@@ -0,0 +1,43 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.yonge.cooleshow.biz.dal.wrapper.DivBackRecordWrapper;
+import com.yonge.cooleshow.biz.dal.entity.DivBackRecord;
+
+/**
+ * 分账归还记录
+ * 2023-10-18 10:59:05
+ */
+public interface DivBackRecordService extends IService<DivBackRecord>  {
+
+	/**
+     * 查询详情
+     * @param id 详情ID
+     * @return DivBackRecord
+     */
+	DivBackRecord detail(Long id);
+
+    /**
+     * 分页查询
+     * @param page IPage<DivBackRecord>
+     * @param query DivBackRecordWrapper.DivBackRecordQuery
+     * @return IPage<DivBackRecord>
+     */
+    IPage<DivBackRecord> selectPage(IPage<DivBackRecord> page, DivBackRecordWrapper.DivBackRecordQuery query);
+	
+    /**
+     * 添加
+     * @param divBackRecord DivBackRecordWrapper.DivBackRecord
+     * @return Boolean
+     */
+     Boolean add(DivBackRecordWrapper.DivBackRecord divBackRecord);   
+
+    /**
+     * 更新
+     * @param divBackRecord DivBackRecordWrapper.DivBackRecord
+     * @return Boolean
+     */
+     Boolean update(DivBackRecordWrapper.DivBackRecord divBackRecord);
+     
+}

+ 8 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/PaymentDivMemberRecordService.java

@@ -95,4 +95,12 @@ public interface PaymentDivMemberRecordService extends IService<PaymentDivMember
      * 活动
      */
     void activity(UserOrderDetailVo userOrderDetailVo);
+
+    /**
+     * 根据订单查询分账记录
+     *
+     * @param orderNo 订单编号
+     * @return
+     */
+    List<PaymentDivMemberRecord> getByOrderNo(String orderNo);
 }

+ 2 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserOrderRefundService.java

@@ -84,4 +84,6 @@ public interface UserOrderRefundService extends IService<UserOrderRefund>  {
 	HttpResponseResult<UserOrderRefundBill> orderRefound(String orderNo);
 
 	void orderRefundSuccessBizHandle(Long refundId);
+
+    void orderRefundSuccessBizHandleByOrderNo(String orderNo);
 }

+ 66 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/DivBackRecordServiceImpl.java

@@ -0,0 +1,66 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import org.springframework.beans.BeanUtils;
+import lombok.extern.slf4j.Slf4j;
+import com.yonge.cooleshow.biz.dal.entity.DivBackRecord;
+import com.yonge.cooleshow.biz.dal.wrapper.DivBackRecordWrapper;
+import com.yonge.cooleshow.biz.dal.mapper.DivBackRecordMapper;
+import com.yonge.cooleshow.biz.dal.service.DivBackRecordService;
+
+/**
+ * 分账归还记录
+ * 2023-10-18 10:59:05
+ */
+@Slf4j
+@Service
+public class DivBackRecordServiceImpl extends ServiceImpl<DivBackRecordMapper, DivBackRecord> implements DivBackRecordService {
+
+	/**
+     * 查询详情
+     * @param id 详情ID
+     * @return DivBackRecord
+     */
+	@Override
+    public DivBackRecord detail(Long id) {
+        
+        return baseMapper.selectById(id);
+    }
+    
+    /**
+     * 分页查询
+     * @param page IPage<DivBackRecord>
+     * @param query DivBackRecordWrapper.DivBackRecordQuery
+     * @return IPage<DivBackRecord>
+     */
+    @Override
+    public IPage<DivBackRecord> selectPage(IPage<DivBackRecord> page, DivBackRecordWrapper.DivBackRecordQuery query) {
+        
+        return page.setRecords(baseMapper.selectPage(page, query));
+    }
+	
+    /**
+     * 添加
+     * @param divBackRecord DivBackRecordWrapper.DivBackRecord
+     * @return Boolean
+     */
+    @Override
+    public Boolean add(DivBackRecordWrapper.DivBackRecord divBackRecord) {    	
+        
+        return this.save(JSON.parseObject(divBackRecord.jsonString(), DivBackRecord.class));
+    }
+
+    /**
+     * 更新
+     * @param divBackRecord DivBackRecordWrapper.DivBackRecord
+     * @return Boolean
+     */
+    @Override
+    public Boolean update(DivBackRecordWrapper.DivBackRecord divBackRecord){
+
+        return this.updateById(JSON.parseObject(divBackRecord.jsonString(), DivBackRecord.class));       
+    }
+}

+ 7 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/PaymentDivMemberRecordServiceImpl.java

@@ -780,6 +780,13 @@ public class PaymentDivMemberRecordServiceImpl extends ServiceImpl<PaymentDivMem
         saveData(userPaymentOrder, tenantdivMap, teacherMap, bizMap, serviceFeeAmount);
     }
 
+    @Override
+    public List<PaymentDivMemberRecord> getByOrderNo(String orderNo) {
+        return this.lambdaQuery()
+            .eq(PaymentDivMemberRecord::getOrderNo, orderNo)
+            .list();
+    }
+
 
     // 写入数据库
     private void saveData(UserOrderDetailVo userPaymentOrder, Map<Long, BigDecimal> tenantdivMap, Map<Long, BigDecimal> teacherMap, Map<Long, BigDecimal> bizMap, BigDecimal serviceFeeAmount) {

+ 25 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderRefundServiceImpl.java

@@ -637,6 +637,31 @@ public class UserOrderRefundServiceImpl extends ServiceImpl<UserOrderRefundDao,
         }
     }
 
+
+    /**
+     * 处理退款业务
+     *
+     * @param orderNo 退款单id
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void orderRefundSuccessBizHandleByOrderNo(String orderNo) {
+        //处理业务
+        OrderDetailSearch search = new OrderDetailSearch();
+        search.setOrderNo(orderNo);
+        List<UserOrderDetailVo> userOrderDetails = orderDetailService.selectList(search);
+        UserOrder order = userOrderService.getByOrderNo(orderNo);
+
+        for (UserOrderDetailVo vo : userOrderDetails) {
+            Consumer<UserOrderDetailVo> refundAfterConsumer = refundSuccess.get(vo.getGoodType());
+            if (!Objects.isNull(refundAfterConsumer)) {
+                refundAfterConsumer.accept(vo);
+            }
+            vo.setPaymentVersion(order.getPaymentVersion());
+            accountHandle(vo);
+        }
+    }
+
     /**
      * 处理退款后账户
      *

+ 117 - 43
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserPaymentCoreServiceImpl.java

@@ -12,6 +12,7 @@ import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
 import com.microsvc.toolkit.middleware.payment.common.api.BasePaymentService;
 import com.microsvc.toolkit.middleware.payment.common.api.PaymentServiceContext;
 import com.microsvc.toolkit.middleware.payment.common.api.entity.*;
+import com.microsvc.toolkit.middleware.payment.common.api.enums.DivideBackStatus;
 import com.microsvc.toolkit.middleware.payment.common.api.enums.PaymentStatus;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.*;
@@ -131,6 +132,11 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
     private UserOrderRefundBillService userOrderRefundBillService;
 
 
+    @Autowired
+    private TenantMemberService tenantMemberService;
+
+    @Autowired
+    private DivBackRecordService divBackRecordService;
 
 
     // 订单商品参数校验,获取订单支付金额
@@ -1258,55 +1264,123 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
         // 执行状态锁定
         String lockName = redisCacheService.getPaymentCacheKey(paymentOrder.getOrderNo());
         DistributedLock.of(redissonClient).runIfLockCanGet(lockName, () -> {
-            // 提交退款申请记录
-            UserOrderRefund userRefundOrder = new UserOrderRefund();
-            userRefundOrder.setUserId(paymentOrder.getId());
-            userRefundOrder.setOrderId(paymentOrder.getId());
-            userRefundOrder.setOrderNo(paymentOrder.getOrderNo());
-            userRefundOrder.setOredrDetilIds(detail.getOrderDetailList().stream().map(o-> o.getId().toString()).collect(Collectors.joining(",")));
-            userRefundOrder.setStatus(AuthStatusEnum.PASS);
-            userRefundOrder.setApplyAmount(paymentOrder.getPaymentCashAmount());
-            userRefundOrder.setActualAmount(paymentOrder.getPaymentCashAmount());
-            userRefundOrder.setReason(reason);
-            userOrderRefundService.save(userRefundOrder);
-
-            //入退款单表
-            UserOrderRefundBill orderRefundBill = new UserOrderRefundBill();
-            orderRefundBill.setRefundId(userRefundOrder.getId());
-            orderRefundBill.setBillNo(IdWorker.getIdStr());
-            orderRefundBill.setRefundAmt(userRefundOrder.getActualAmount());
-
-
-            RefundOrder refundOrder = new RefundOrder();
-            refundOrder.setUserId(paymentOrder.getUserId().toString());
-            refundOrder.setMerOrderNo(orderRefundBill.getBillNo());
-            refundOrder.setRefundAmount(orderRefundBill.getRefundAmt());
-            refundOrder.setOrderAmount(paymentOrder.getPaymentCashAmount());
-            refundOrder.setReason(reason);
-            refundOrder.setTransNo(paymentOrder.getTransNo());
-            refundOrder.setPaymentOrderNo(paymentOrder.getOrderNo());
-
-            // 执行状态锁定
-            String lockNameInner = redisCacheService.getPaymentCacheKey(orderRefundBill.getBillNo());
-            DistributedLock.of(redissonClient).runIfLockCanGet(lockNameInner, () -> {
-                RefundResp refundResp = paymentServiceContext.getPaymentService(paymentOrder.getPaymentVendor()).refund(refundOrder);
-                // 申请请求失败
-                if (PaymentStatus.FAILED == refundResp.getPaymentStatus()) {
-                    orderRefundBill.setStatus(TradeStatusEnum.failed);
-                    orderRefundBill.setPayFailMsg(refundResp.getMsg());
-                } else {
-                    orderRefundBill.setTransNo(refundResp.getTransNo());
-                    orderRefundBill.setStatus(TradeStatusEnum.pending);
+
+            // 如果是易宝的订单,查询分账是否给到子账户,没有给子账户的直接退款
+
+            // 分账给子账户的 先 分账归还,如果归还成功,再退款,归还失败,不退款,退款后的逻辑还是继续走
+
+            boolean refundFlag = true;
+            if (paymentOrder.getPaymentVendor().equals(EPayerType.YEEPAY.getDesc())) {
+                List<PaymentDivMemberRecord> records = paymentDivMemberRecordService.getByOrderNo(paymentOrder.getOrderNo());
+
+                for (PaymentDivMemberRecord record : records) {
+                    if (record.getTenantEnterFlag()) {
+
+                        refundFlag = saveDivBackRecord(paymentOrder, record);
+
+                    }
                 }
-                userOrderRefundBillService.save(orderRefundBill);
+            }
 
-                //处理退款业务
-               userOrderRefundService.orderRefundSuccessBizHandle(userRefundOrder.getId());
+            if (refundFlag) {
+                // 提交退款申请记录
+                UserOrderRefund userRefundOrder = new UserOrderRefund();
+                userRefundOrder.setUserId(paymentOrder.getId());
+                userRefundOrder.setOrderId(paymentOrder.getId());
+                userRefundOrder.setOrderNo(paymentOrder.getOrderNo());
+                userRefundOrder.setOredrDetilIds(detail.getOrderDetailList().stream().map(o -> o.getId().toString()).collect(Collectors.joining(",")));
+                userRefundOrder.setStatus(AuthStatusEnum.PASS);
+                userRefundOrder.setApplyAmount(paymentOrder.getPaymentCashAmount());
+                userRefundOrder.setActualAmount(paymentOrder.getPaymentCashAmount());
+                userRefundOrder.setReason(reason);
+                userOrderRefundService.save(userRefundOrder);
+
+                //入退款单表
+                UserOrderRefundBill orderRefundBill = new UserOrderRefundBill();
+                orderRefundBill.setRefundId(userRefundOrder.getId());
+                orderRefundBill.setBillNo(IdWorker.getIdStr());
+                orderRefundBill.setRefundAmt(userRefundOrder.getActualAmount());
+
+
+                RefundOrder refundOrder = new RefundOrder();
+                refundOrder.setUserId(paymentOrder.getUserId().toString());
+                refundOrder.setMerOrderNo(orderRefundBill.getBillNo());
+                refundOrder.setRefundAmount(orderRefundBill.getRefundAmt());
+                refundOrder.setOrderAmount(paymentOrder.getPaymentCashAmount());
+                refundOrder.setReason(reason);
+                refundOrder.setTransNo(paymentOrder.getTransNo());
+                refundOrder.setPaymentOrderNo(paymentOrder.getOrderNo());
+
+                // 执行状态锁定
+                String lockNameInner = redisCacheService.getPaymentCacheKey(orderRefundBill.getBillNo());
+                DistributedLock.of(redissonClient).runIfLockCanGet(lockNameInner, () -> {
+                    RefundResp refundResp = paymentServiceContext.getPaymentService(paymentOrder.getPaymentVendor()).refund(refundOrder);
+                    // 申请请求失败
+                    if (PaymentStatus.FAILED == refundResp.getPaymentStatus()) {
+                        orderRefundBill.setStatus(TradeStatusEnum.failed);
+                        orderRefundBill.setPayFailMsg(refundResp.getMsg());
+                    } else {
+                        orderRefundBill.setTransNo(refundResp.getTransNo());
+                        orderRefundBill.setStatus(TradeStatusEnum.pending);
+                    }
+                    userOrderRefundBillService.save(orderRefundBill);
 
-            }, 10L, TimeUnit.SECONDS);
+                }, 10L, TimeUnit.SECONDS);
+            }
 
+            //处理退款业务
+            userOrderRefundService.orderRefundSuccessBizHandleByOrderNo(paymentOrder.getOrderNo());
         }, 10L, TimeUnit.SECONDS);
 
     }
 
+    private boolean saveDivBackRecord(UserPaymentOrderWrapper.UserPaymentOrder paymentOrder, PaymentDivMemberRecord record) {
+
+
+        BasePaymentService paymentService = paymentServiceContext.getPaymentService(paymentOrder.getPaymentVendor());
+
+        boolean refundFlag = true;
+        DivBackRecord divBackRecord = new DivBackRecord();
+        divBackRecord.setPaymentDivMemberRecordId(record.getId());
+        divBackRecord.setDivideBackOrderNo(IdWorker.getIdStr());
+        divBackRecord.setTimes(1);
+
+        // 分账数据
+        DivideReq.DivideBackDetail divideBackDetail = DivideReq.DivideBackDetail.builder()
+            .amount(record.getAmount())
+            .divideDetailNo(record.getTransNo())
+            .divideBackReason("订单退款")
+            .build();
+
+        DivideReq.MemberDivideBack memberDivideBack = DivideReq.MemberDivideBack.builder()
+            .payerName(EPayerType.YEEPAY.getDesc())
+            .memberId(record.getMemberId())
+            .platformPayeeMemberId(paymentService.getPaymentConfig().getMerchantId())
+            .divideBackOrderNo(divBackRecord.getDivideBackOrderNo())
+            .payOrderNo(paymentOrder.getOrderNo())
+            .transNo(paymentOrder.getTransNo())
+            .divideBackDetail(Lists.newArrayList(divideBackDetail))
+            .build();
+
+
+        try {
+
+            DivideResp.DivideBack divideBack = paymentService.divideBack(tenantMemberService
+                .getMerchantConfig(paymentOrder.getPaymentVendor()), memberDivideBack);
+            if (divideBack.getStatus() != DivideBackStatus.SUCCESS) {
+                refundFlag = false;
+            }
+            divBackRecord.setReason(divideBack.getReason());
+            divBackRecord.setDivideBackTransNo(divideBack.getDivideBackTransNo());
+            divBackRecord.setStatus(divideBack.getStatus().name());
+
+        }catch (Exception e) {
+            log.error("分账回归失败orderNo={}", memberDivideBack.getDivideBackOrderNo(), e);
+            refundFlag = false;
+            divBackRecord.setReason(e.getMessage());
+        }
+        divBackRecordService.save(divBackRecord);
+        return refundFlag;
+    }
+
 }

+ 63 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/DivBackRecordWrapper.java

@@ -0,0 +1,63 @@
+package com.yonge.cooleshow.biz.dal.wrapper;
+
+import com.alibaba.fastjson.JSON;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import java.util.Optional;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * 分账归还记录
+ * 2023-10-18 10:59:05
+ */
+@ApiModel(value = "DivBackRecordWrapper对象", description = "分账归还记录查询对象")
+public class DivBackRecordWrapper {
+
+    @Data
+	@Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" DivBackRecordQuery-分账归还记录")
+    public static class DivBackRecordQuery implements QueryInfo {
+    
+    	@ApiModelProperty("当前页")
+        private Integer page;
+        
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+        
+        @ApiModelProperty("关键字匹配")
+		private String keyword;
+        
+        public String getKeyword() {
+            return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
+        }
+        
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static DivBackRecordQuery from(String json) {
+            return JSON.parseObject(json, DivBackRecordQuery.class);
+        }
+    }  
+
+	@ApiModel(" DivBackRecord-分账归还记录")
+    public static class DivBackRecord {
+        
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static DivBackRecord from(String json) {
+            return JSON.parseObject(json, DivBackRecord.class);
+        }
+	}
+
+}

+ 26 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/DivBackRecordMapper.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE  mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.yonge.cooleshow.biz.dal.mapper.DivBackRecordMapper">
+
+	 
+    
+    <!-- 表字段 -->
+    <sql id="baseColumns">
+         t.id_ AS id
+        , t.payment_div_member_record_id_ AS paymentDivMemberRecordId
+        , t.divide_back_order_no_ AS divideBackOrderNo
+        , t.divide_back_trans_no_ AS divideBackTransNo
+        , t.status_ AS status
+        , t.reason_ AS reason
+        , t.times_ AS times
+        , t.create_time_ AS createTime
+        , t.update_time_ AS updateTime
+        </sql> 
+    
+    <select id="selectPage" resultType="com.yonge.cooleshow.biz.dal.entity.DivBackRecord">
+		SELECT         
+        	<include refid="baseColumns" />
+		FROM div_back_record t
+	</select>
+    
+</mapper>